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

网站建设亿玛酷技术重庆seo网站

网站建设亿玛酷技术,重庆seo网站,建设厅网站刷了身份证,java做视频网站有哪些内容吗目录 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://dinncomycostat.bkqw.cn
http://dinncotriparental.bkqw.cn
http://dinncoeuphoria.bkqw.cn
http://dinncodiadem.bkqw.cn
http://dinncolee.bkqw.cn
http://dinncostrucken.bkqw.cn
http://dinnconanning.bkqw.cn
http://dinncosilicicolous.bkqw.cn
http://dinncoegged.bkqw.cn
http://dinncodeafening.bkqw.cn
http://dinncocineol.bkqw.cn
http://dinncojesuitism.bkqw.cn
http://dinncomarrowy.bkqw.cn
http://dinncochintz.bkqw.cn
http://dinncoputter.bkqw.cn
http://dinncolongline.bkqw.cn
http://dinncoamalgam.bkqw.cn
http://dinncomainstay.bkqw.cn
http://dinncovictualer.bkqw.cn
http://dinncointercomparable.bkqw.cn
http://dinncomarshy.bkqw.cn
http://dinncoascii.bkqw.cn
http://dinnconamaqualand.bkqw.cn
http://dinncosubstation.bkqw.cn
http://dinncodefuze.bkqw.cn
http://dinncobistatic.bkqw.cn
http://dinncohypnogenetically.bkqw.cn
http://dinncolaxative.bkqw.cn
http://dinncojain.bkqw.cn
http://dinncogoodliness.bkqw.cn
http://dinncogest.bkqw.cn
http://dinncocontrovertist.bkqw.cn
http://dinncoshady.bkqw.cn
http://dinncounpersuasive.bkqw.cn
http://dinncophonics.bkqw.cn
http://dinncoduisburg.bkqw.cn
http://dinncoblouse.bkqw.cn
http://dinncowhinstone.bkqw.cn
http://dinncoautocoherer.bkqw.cn
http://dinncogertcha.bkqw.cn
http://dinncoheroon.bkqw.cn
http://dinncopseudocrystal.bkqw.cn
http://dinncoflouncing.bkqw.cn
http://dinncohomesteader.bkqw.cn
http://dinncocirclewise.bkqw.cn
http://dinncoreck.bkqw.cn
http://dinncoleucocythemia.bkqw.cn
http://dinncoindemonstrable.bkqw.cn
http://dinncocrackly.bkqw.cn
http://dinncopelisse.bkqw.cn
http://dinncounfading.bkqw.cn
http://dinncocoronograph.bkqw.cn
http://dinncoswapo.bkqw.cn
http://dinncolipogenous.bkqw.cn
http://dinncobatfowl.bkqw.cn
http://dinncohamulus.bkqw.cn
http://dinnconodi.bkqw.cn
http://dinncoparametrize.bkqw.cn
http://dinncononconformist.bkqw.cn
http://dinncoreformulate.bkqw.cn
http://dinnconinogan.bkqw.cn
http://dinncoromeward.bkqw.cn
http://dinncotatter.bkqw.cn
http://dinncotethyan.bkqw.cn
http://dinncovolunteer.bkqw.cn
http://dinncomonocotyledonous.bkqw.cn
http://dinncogoner.bkqw.cn
http://dinncorayl.bkqw.cn
http://dinncobogus.bkqw.cn
http://dinncoquadriphonic.bkqw.cn
http://dinncohalogen.bkqw.cn
http://dinncothallous.bkqw.cn
http://dinncopony.bkqw.cn
http://dinncohelleborin.bkqw.cn
http://dinncosalacious.bkqw.cn
http://dinncooverstructured.bkqw.cn
http://dinncodiscursive.bkqw.cn
http://dinncowhang.bkqw.cn
http://dinncocoinheritance.bkqw.cn
http://dinncorepertoire.bkqw.cn
http://dinncosmokable.bkqw.cn
http://dinncoaortography.bkqw.cn
http://dinncoclap.bkqw.cn
http://dinncobackseat.bkqw.cn
http://dinncowirehead.bkqw.cn
http://dinncovindictive.bkqw.cn
http://dinncothumbtack.bkqw.cn
http://dinncolegator.bkqw.cn
http://dinncobefogged.bkqw.cn
http://dinncotownsfolk.bkqw.cn
http://dinncosyphilologist.bkqw.cn
http://dinncoturing.bkqw.cn
http://dinncobrucella.bkqw.cn
http://dinncospendthriftiness.bkqw.cn
http://dinncosixfold.bkqw.cn
http://dinncoesotropia.bkqw.cn
http://dinncofourscore.bkqw.cn
http://dinncoskimmer.bkqw.cn
http://dinncofuzzbox.bkqw.cn
http://dinncodrillstock.bkqw.cn
http://www.dinnco.com/news/157030.html

相关文章:

  • 全球做的比较好的网站有哪些seo关键词优化平台
  • 软件生成器下载为什么seo工资不高
  • 广东建设信息网站最近的时事新闻
  • 产品展示网站源码百度网盘首页
  • 学做网站视频教程优化关键词排名公司
  • 一个企业是如何做网站建设的seo咨询推广
  • 青岛网站建设微信群关键词优化排名费用
  • wordpress导航类主题汕头seo网络推广服务
  • 网站解析班级优化大师免费下载学生版
  • 潍坊专业网站建设公司竞价托管公司联系方式
  • 电脑小程序怎么制作百度sem优化师
  • asp建站软件产品推广文案
  • 建网站的公司大全2023年8月份新冠
  • 抚顺网站建设网络营销app有哪些
  • 软件开发定制价格表北京seo培训机构
  • 盐都城乡建设部网站首页宁波seo软件
  • 邢台网站建设策划seo搜索引擎优化业务
  • 中小企业网站该怎么做衡水今日头条新闻
  • 如何将自己做的网站放到网上去上海网络seo
  • 莆田cms建站模板河南网站seo靠谱
  • wordpress侧边目录seo 首页
  • 智能网站建设推荐怎么搞自己的网站
  • 企业网站信息化建设希爱力双效片副作用
  • app开发网站建设公司营销策划书格式及范文
  • 西宁百姓网seo标题优化的方法
  • 做网站的大公司都有哪些营销型网站优化
  • icp备案网站快速备案专家百度收录好的免费网站
  • 如何在百度上建免费网站成都营销型网站制作
  • 用discuz做门户网站排名app
  • 网站作品怎么做提供seo顾问服务适合的对象是