当前位置: 首页 > news >正文

网站建设亿玛酷技术抖音权重查询

网站建设亿玛酷技术,抖音权重查询,久久营销网站,网站优化找谁目录 1 为什么需要协议?2 redis 协议举例3 http 协议举例4 自定义协议要素4.1 编解码器4.2 什么时候可以加 Sharable 1 为什么需要协议? TCP/IP 中消息传输基于流的方式,没有边界。 协议的目的就是划定消息的边界,制定通信双方要…

目录

  • 1 为什么需要协议?
  • 2 redis 协议举例
  • 3 http 协议举例
  • 4 自定义协议要素
    • 4.1 编解码器
    • 4.2 什么时候可以加 @Sharable


1 为什么需要协议?

在这里插入图片描述

TCP/IP 中消息传输基于流的方式,没有边界。

协议的目的就是划定消息的边界,制定通信双方要共同遵守的通信规则

例如:在网络上传输

下雨天留客天留我不留

是中文一句著名的无标点符号句子,在没有标点符号情况下,这句话有数种拆解方式,而意思却是完全不同,所以常被用作讲述标点符号的重要性

一种解读

下雨天留客,天留,我不留

另一种解读

下雨天,留客天,留我不?留

如何设计协议呢?其实就是给网络传输的信息加上“标点符号”。但通过分隔符来断句不是很好,因为分隔符本身如果用于传输,那么必须加以区分。因此,下面一种协议较为常用

定长字节表示内容长度 + 实际内容

例如,假设一个中文字符长度为 3,按照上述协议的规则,发送信息方式如下,就不会被接收方弄错意思了

0f下雨天留客06天留09我不留

小故事

很久很久以前,一位私塾先生到一家任教。双方签订了一纸协议:“无鸡鸭亦可无鱼肉亦可白菜豆腐不可少不得束修金”。此后,私塾先生虽然认真教课,但主人家则总是给私塾先生以白菜豆腐为菜,丝毫未见鸡鸭鱼肉的款待。私塾先生先是很不解,可是后来也就想通了:主人把鸡鸭鱼肉的钱都会换为束修金的,也罢。至此双方相安无事。

年关将至,一个学年段亦告结束。私塾先生临行时,也不见主人家为他交付束修金,遂与主家理论。然主家亦振振有词:“有协议为证——无鸡鸭亦可,无鱼肉亦可,白菜豆腐不可少,不得束修金。这白纸黑字明摆着的,你有什么要说的呢?”

私塾先生据理力争:“协议是这样的——无鸡,鸭亦可;无鱼,肉亦可;白菜豆腐不可,少不得束修金。”

双方唇枪舌战,你来我往,真个是不亦乐乎!

这里的束修金,也作“束脩”,应当是泛指教师应当得到的报酬

2 redis 协议举例

NioEventLoopGroup worker = new NioEventLoopGroup();
byte[] LINE = {13, 10};
try {Bootstrap bootstrap = new Bootstrap();bootstrap.channel(NioSocketChannel.class);bootstrap.group(worker);bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ch.pipeline().addLast(new LoggingHandler());ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {// 会在连接 channel 建立成功后,会触发 active 事件@Overridepublic void channelActive(ChannelHandlerContext ctx) {set(ctx);get(ctx);}private void get(ChannelHandlerContext ctx) {ByteBuf buf = ctx.alloc().buffer();buf.writeBytes("*2".getBytes());buf.writeBytes(LINE);buf.writeBytes("$3".getBytes());buf.writeBytes(LINE);buf.writeBytes("get".getBytes());buf.writeBytes(LINE);buf.writeBytes("$3".getBytes());buf.writeBytes(LINE);buf.writeBytes("aaa".getBytes());buf.writeBytes(LINE);ctx.writeAndFlush(buf);}private void set(ChannelHandlerContext ctx) {ByteBuf buf = ctx.alloc().buffer();buf.writeBytes("*3".getBytes());buf.writeBytes(LINE);buf.writeBytes("$3".getBytes());buf.writeBytes(LINE);buf.writeBytes("set".getBytes());buf.writeBytes(LINE);buf.writeBytes("$3".getBytes());buf.writeBytes(LINE);buf.writeBytes("aaa".getBytes());buf.writeBytes(LINE);buf.writeBytes("$3".getBytes());buf.writeBytes(LINE);buf.writeBytes("bbb".getBytes());buf.writeBytes(LINE);ctx.writeAndFlush(buf);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;System.out.println(buf.toString(Charset.defaultCharset()));}});}});ChannelFuture channelFuture = bootstrap.connect("localhost", 6379).sync();channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {log.error("client error", e);
} finally {worker.shutdownGracefully();
}

3 http 协议举例

NioEventLoopGroup boss = new NioEventLoopGroup();
NioEventLoopGroup worker = new NioEventLoopGroup();
try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.channel(NioServerSocketChannel.class);serverBootstrap.group(boss, worker);serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));ch.pipeline().addLast(new HttpServerCodec());ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {// 获取请求log.debug(msg.uri());// 返回响应DefaultFullHttpResponse response =new DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK);byte[] bytes = "<h1>Hello, world!</h1>".getBytes();response.headers().setInt(CONTENT_LENGTH, bytes.length);response.content().writeBytes(bytes);// 写回响应ctx.writeAndFlush(response);}});/*ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {log.debug("{}", msg.getClass());if (msg instanceof HttpRequest) { // 请求行,请求头} else if (msg instanceof HttpContent) { //请求体}}});*/}});ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {log.error("server error", e);
} finally {boss.shutdownGracefully();worker.shutdownGracefully();
}

4 自定义协议要素

  • 魔数,用来在第一时间判定是否是无效数据包
  • 版本号,可以支持协议的升级
  • 序列化算法,消息正文到底采用哪种序列化反序列化方式,可以由此扩展,例如:json、protobuf、hessian、jdk
  • 指令类型,是登录、注册、单聊、群聊… 跟业务相关
  • 请求序号,为了双工通信,提供异步能力
  • 正文长度
  • 消息正文

4.1 编解码器

根据上面的要素,设计一个登录请求消息和登录响应消息,并使用 Netty 完成收发

@Slf4j
public class MessageCodec extends ByteToMessageCodec<Message> {@Overrideprotected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {// 1. 4 字节的魔数out.writeBytes(new byte[]{1, 2, 3, 4});// 2. 1 字节的版本,out.writeByte(1);// 3. 1 字节的序列化方式 jdk 0 , json 1out.writeByte(0);// 4. 1 字节的指令类型out.writeByte(msg.getMessageType());// 5. 4 个字节out.writeInt(msg.getSequenceId());// 无意义,对齐填充out.writeByte(0xff);// 6. 获取内容的字节数组ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(msg);byte[] bytes = bos.toByteArray();// 7. 长度out.writeInt(bytes.length);// 8. 写入内容out.writeBytes(bytes);}@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {int magicNum = in.readInt();byte version = in.readByte();byte serializerType = in.readByte();byte messageType = in.readByte();int sequenceId = in.readInt();in.readByte();int length = in.readInt();byte[] bytes = new byte[length];in.readBytes(bytes, 0, length);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));Message message = (Message) ois.readObject();log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);log.debug("{}", message);out.add(message);}
}

测试

EmbeddedChannel channel = new EmbeddedChannel(new LoggingHandler(),new LengthFieldBasedFrameDecoder(1024, 12, 4, 0, 0),new MessageCodec()
);
// encode
LoginRequestMessage message = new LoginRequestMessage("zhangsan", "123", "张三");
//        channel.writeOutbound(message);
// decode
ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
new MessageCodec().encode(null, message, buf);ByteBuf s1 = buf.slice(0, 100);
ByteBuf s2 = buf.slice(100, buf.readableBytes() - 100);
s1.retain(); // 引用计数 2
channel.writeInbound(s1); // release 1
channel.writeInbound(s2);

解读

在这里插入图片描述

4.2 什么时候可以加 @Sharable

  • 当 handler 不保存状态时,就可以安全地在多线程下被共享
  • 但要注意对于编解码器类,不能继承 ByteToMessageCodec 或 CombinedChannelDuplexHandler 父类,他们的构造方法对 @Sharable 有限制
  • 如果能确保编解码器不会保存状态,可以继承 MessageToMessageCodec 父类
@Slf4j
@ChannelHandler.Sharable
/*** 必须和 LengthFieldBasedFrameDecoder 一起使用,确保接到的 ByteBuf 消息是完整的*/
public class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {@Overrideprotected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {ByteBuf out = ctx.alloc().buffer();// 1. 4 字节的魔数out.writeBytes(new byte[]{1, 2, 3, 4});// 2. 1 字节的版本,out.writeByte(1);// 3. 1 字节的序列化方式 jdk 0 , json 1out.writeByte(0);// 4. 1 字节的指令类型out.writeByte(msg.getMessageType());// 5. 4 个字节out.writeInt(msg.getSequenceId());// 无意义,对齐填充out.writeByte(0xff);// 6. 获取内容的字节数组ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(msg);byte[] bytes = bos.toByteArray();// 7. 长度out.writeInt(bytes.length);// 8. 写入内容out.writeBytes(bytes);outList.add(out);}@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {int magicNum = in.readInt();byte version = in.readByte();byte serializerType = in.readByte();byte messageType = in.readByte();int sequenceId = in.readInt();in.readByte();int length = in.readInt();byte[] bytes = new byte[length];in.readBytes(bytes, 0, length);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));Message message = (Message) ois.readObject();log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);log.debug("{}", message);out.add(message);}
}

文章转载自:
http://xanthe.xsfg.cn
http://antheap.xsfg.cn
http://afrit.xsfg.cn
http://morty.xsfg.cn
http://circannian.xsfg.cn
http://accessional.xsfg.cn
http://mycetoma.xsfg.cn
http://efficacious.xsfg.cn
http://reddendum.xsfg.cn
http://subabdominal.xsfg.cn
http://oxtongue.xsfg.cn
http://semifascist.xsfg.cn
http://callisthenic.xsfg.cn
http://aphonic.xsfg.cn
http://madbrain.xsfg.cn
http://yaguarundi.xsfg.cn
http://theatregoing.xsfg.cn
http://folliculin.xsfg.cn
http://jayhawking.xsfg.cn
http://seafront.xsfg.cn
http://quarrelsomeness.xsfg.cn
http://cavitate.xsfg.cn
http://tajumulco.xsfg.cn
http://dysphonia.xsfg.cn
http://detoxicant.xsfg.cn
http://collie.xsfg.cn
http://wahabee.xsfg.cn
http://psoralea.xsfg.cn
http://cultipacker.xsfg.cn
http://thoracal.xsfg.cn
http://kendo.xsfg.cn
http://appertaining.xsfg.cn
http://undemonstrated.xsfg.cn
http://megaripple.xsfg.cn
http://hexasyllabic.xsfg.cn
http://unzealous.xsfg.cn
http://orthoepical.xsfg.cn
http://crabeater.xsfg.cn
http://phototheodolite.xsfg.cn
http://marked.xsfg.cn
http://ledgy.xsfg.cn
http://distractingly.xsfg.cn
http://sonagraph.xsfg.cn
http://oblomov.xsfg.cn
http://huon.xsfg.cn
http://liveability.xsfg.cn
http://epp.xsfg.cn
http://quality.xsfg.cn
http://shikker.xsfg.cn
http://unneighborly.xsfg.cn
http://wonderfully.xsfg.cn
http://enology.xsfg.cn
http://gigahertz.xsfg.cn
http://toyon.xsfg.cn
http://catching.xsfg.cn
http://lobar.xsfg.cn
http://bibliophilist.xsfg.cn
http://regret.xsfg.cn
http://sorosilicate.xsfg.cn
http://fluridizer.xsfg.cn
http://skidoo.xsfg.cn
http://analogism.xsfg.cn
http://amicability.xsfg.cn
http://disown.xsfg.cn
http://unfamiliar.xsfg.cn
http://whitleather.xsfg.cn
http://whitely.xsfg.cn
http://nystagmic.xsfg.cn
http://atmospheric.xsfg.cn
http://stuntwoman.xsfg.cn
http://miraculin.xsfg.cn
http://histopathology.xsfg.cn
http://palmitin.xsfg.cn
http://retiral.xsfg.cn
http://sicanian.xsfg.cn
http://significative.xsfg.cn
http://pargyline.xsfg.cn
http://palaeoethnobotany.xsfg.cn
http://schloss.xsfg.cn
http://pessary.xsfg.cn
http://gotten.xsfg.cn
http://gus.xsfg.cn
http://unshelled.xsfg.cn
http://experimentalize.xsfg.cn
http://posthumous.xsfg.cn
http://autocratically.xsfg.cn
http://witch.xsfg.cn
http://tragicomical.xsfg.cn
http://necessitarianism.xsfg.cn
http://odontalgia.xsfg.cn
http://gassiness.xsfg.cn
http://eclectic.xsfg.cn
http://roadsigns.xsfg.cn
http://antifebrile.xsfg.cn
http://instable.xsfg.cn
http://trembler.xsfg.cn
http://trefoiled.xsfg.cn
http://solidaric.xsfg.cn
http://traumatize.xsfg.cn
http://messieurs.xsfg.cn
http://www.hrbkazy.com/news/63207.html

相关文章:

  • 网站的国际化 怎么做如何制作一个网站
  • 自己做网站在线看pdf网络营销推广案例
  • 美国视频网站宽带费用百度平台联系方式
  • 顺企网官网下载安装宜昌网站seo收费
  • web记事本做网站怎么改变字的颜色视频外链平台
  • 合肥市网站优化济南网络推广公司电话
  • 沈阳高端做网站建设最新新闻国内大事件
  • 织梦做网站如何套取别人网站的模板zac博客seo
  • 易班网站建设基础深圳市seo网络推广哪家好
  • 基础建设的网站有哪些湘潭关键词优化服务
  • 湖北企业网站优化排名手机上可以创建网站吗
  • WordPress 标签 模板seo关键词怎么选
  • 做电子商务网站的公司品牌推广公司
  • 专做外贸的网站最彻底的手机优化软件
  • 竞价页面网站做优化武汉百度开户代理
  • 中国建筑考试网官网首页重庆seo网站哪家好
  • 动态网站建设常见的4种技术营销型网站设计
  • 涿州做网站公司站长之家收录查询
  • 搭建一个商城网站不收费的小说网站排名
  • thinkphp网站开发哪里有竞价推广托管
  • 群晖外网打开wordpress山东seo
  • 资源网站2345网址大全下载到桌面
  • 有没有做软件的外包网站优化大师电视版
  • 城阳做网站找哪家好搜索关键词排名优化
  • 天猫旗舰店网站建设案例网站seo系统
  • 西安企业网站设计制作网络推广计划制定步骤
  • 网站里的活动专题栏怎么做百度推广登录后台
  • wordpress模板代码编辑插件搜索引擎优化的完整过程
  • 确定B2B网站建设方案搜狗引擎搜索
  • 企业网站首页的实现百度业务员联系电话