自定义协议与TCP粘包拆包解决_自定义协议 tcp粘包 拆包-程序员宅基地

技术标签: netty  

tcp粘包与拆包

TCP是基于数据流的协议,TCP为提高传输效率,默认使用Nagle算法,会有延迟,往往要收集到足够多的数据后才发送一个TCP段。TCP底层不了解业务数据的含义,它会根据TCP缓冲区的实际情况进行包的划分,所以业务上认为,一个完整的包可能被TCP拆分为多个包进行发送,也可能把多个小包封装成一个大的数据包进行发送,这就是所谓的TCP粘包和拆包问题。

netty实现自定义协议

定义了消息格式的类:

public class MyProtocol {
    
    private int length;
    private byte[] content;
    
    public int getLength() {
    
        return length;
    }
    public void setLength(int length) {
    
        this.length = length;
    }

    public byte[] getContent() {
    
        return content;
    }
    public void setContent(byte[] content) {
    
        this.content = content;
    }
    @Override
    public String toString() {
    
        return "MyProtocol{" +
                "length=" + length +
                ", content=" + new String(content,Charset.forName("utf-8")) +
                '}';
    }
}

自定义协议解码器:

public class MyProtocolDecoder extends ReplayingDecoder<Void> {
    
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    
        int length = in.readInt();
        byte[] content = new byte[length];
        in.readBytes(content);
        MyProtocol myProtocol = new MyProtocol();
        myProtocol.setLength(length);
        myProtocol.setContent(content);
        out.add(myProtocol);
    }
}

自定义协议编码器:

public class MyProtocolEncoder extends MessageToByteEncoder<MyProtocol> {
    
    @Override
    protected void encode(ChannelHandlerContext ctx, MyProtocol msg, ByteBuf out) throws Exception {
    
        int length=msg.getLength();
        byte[] content = msg.getContent();
        out.writeInt(length);
        out.writeBytes(content);
    }
}

客户端业务handler,通道建立连接后,向服务器发送10条数据:

public class MyClientHandler extends SimpleChannelInboundHandler<MyProtocol> {
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MyProtocol msg) throws Exception {
     }
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    
        for(int i=0;i<10;i++){
    
            String message = "from the client";
            int length = message.getBytes(Charset.forName("utf-8")).length;
            byte[] content = message.getBytes(Charset.forName("utf-8"));
            MyProtocol myProtocol = new MyProtocol();
            myProtocol.setLength(length);
            myProtocol.setContent(content);
            ctx.writeAndFlush(myProtocol);
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    
        cause.printStackTrace();
        ctx.close();
    }
}

服务端业务handler:

public class MyServerHandler extends SimpleChannelInboundHandler<MyProtocol> {
    
    private int count;
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MyProtocol msg) throws Exception {
    
        System.out.println(msg);
        System.out.println(++count);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    
        cause.printStackTrace();
        ctx.close();
    }
}

最终在服务器上接收的结果:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xianmingsu/article/details/103685301

智能推荐

Xilinx Spartan-6 FPGA开发板硬件说明书(2)_xilinx sparta6两个指示灯-程序员宅基地

文章浏览阅读920次。8.LED指示灯开发板底板具有1个电源指示灯,以及1个DAC输出波形指示灯,它们分别是C67和C53。图 12图 13图 14图 15核心板具有1个电源指示灯,1个PROGRAM下载指示灯,以及2个用户可编程指示灯,分别是R7,R36,R41和R46。图 16核心板各个用户可编程指示灯对应的CPU引脚如下:表1 LED编号 FPGA管脚 KD1 ..._xilinx sparta6两个指示灯

weblogic配置java参数_修改weblogic jvm启动参数-程序员宅基地

文章浏览阅读1.5k次。进入:D:\Oracle\Middleware\user_projects\domains\base_domain\startWebLogic.cmd在call 上一行增加:set USER_MEM_ARGS=-Xms512m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m例如:@ECHO OFF@REM WARNING: This file i..._wljrecm

程序员必须掌握的英文单词(一)_程序员需要掌握的英语-程序员宅基地

文章浏览阅读4.5k次,点赞29次,收藏131次。程序员英语单词册经过几天的整理将程序员必备的 600 词汇,和有关计算机需要掌握的词汇整理出来,分享给大家学习,希望对你有所帮助。程序员必备的 600 个英语词汇,对于时刻需要和国际接轨的码农们,英语的重要性是毋庸置疑的。尤其是那些胸怀大志的潜在大牛们,想在码农行业闯出一片天地,秒杀身边的小弟们,熟练掌握英语更是实现其目标最关键的因素之一。否则,试想在你捧着某出版社刚刚翻译出来的《JSP ..._程序员需要掌握的英语

vue在IE下报 webpack `Invalid Host/Origin header` 的问题_vue项目报不正确的请求头origin-程序员宅基地

文章浏览阅读295次。本次产生原因:IE某些版本不支持axios //为解决IE 不支持axios import Promise from 'es6-promise'; Promise.polyfill();引入es6-promise后,IE就出现如下错误:原因:应该是webpack出于安全考虑,因为不检查主机的应用程序容易受到DNS重新绑定攻击。但是,在我们的开发环境下,可以禁用掉disableHostCheck这一配置项。解决:在webpack.dev.config.js中..._vue项目报不正确的请求头origin

springboot3.0 整合mybatis-flex1.5.3_spring boot 集成mybatis-flex-程序员宅基地

文章浏览阅读840次。3,config类如果扫描不到,可以添加org.springframework.boot.autoconfigure.AutoConfiguration.imports。1,首先pom文件引入mybatis-flex依赖,mybatis-flex版本为1.5.3。2,创建config配置类,配置mapper的扫描路径,可以设置主键的生成方式等配置,4, 配置application.yml。6,启动测试类,进行测试。_spring boot 集成mybatis-flex

python扩展库numpy的简单介绍_阐述numpy拓展库-程序员宅基地

文章浏览阅读1.7k次。与图像相关的知识。文章目录前言一、图像表示二、Numpy相关介绍1.ndarray对象及常用的属性(1)ndarray.shape属性(2)ndarray.dtype属性(3)numpy的数据类型(4)ndarray.ndim属性(5)ndarray.size属性2.Numpy常用的函数1.创建ndarray对象2.ndarray对象的索引以及切片3.ndarray对象生成随机数总结前言要对一张图片进行处理,首先需要获取这张图片。可以使用相机和手机等工具获取一张彩色图片,并且以一种特定的格式保存在_阐述numpy拓展库

随便推点

pom.xml常用元素(maven)_pom.xml的namespace-程序员宅基地

文章浏览阅读1.8k次。 我想很多初学者对上图&lt;project&gt;标签内的:xmlns、xmlns:xsi、schemaLocation都表示不解,那么今天就科普一下它们代表的含义:xmlns:是xml的命名空间(XML Namespaces),为了避免元素命名冲突。目的是为当前的xml元素命名,以区别其他的同名元素。它有两种命名方式:xmlns="namespaceURI" 默认命名空间 xmlns..._pom.xml的namespace

【Java小项目练习】华容道-经典华容道游戏_头哥实践平台答案java华容道小程序之模拟曹操csdn-程序员宅基地

文章浏览阅读1k次。游戏玩法:可以通过鼠标点击选中人物,然后通过键盘 ↑ ↓ ← → 控制人物移动最后如果曹操处于最下方的正中间,那么就算游戏成功!那么我们看下代码怎么实现吧!..._头哥实践平台答案java华容道小程序之模拟曹操csdn

XML解析_xml文件解析-程序员宅基地

文章浏览阅读1.9k次,点赞6次,收藏6次。将XML文档转换为计算机程序可读取的格式的过程。XML文档中的元素、属性、实体等都需要被解析成程序能够理解的形式,以便程序能够对其进行处理和操作。1.2 解析方式(四种)1.2.1 DOM解析:DOM(文档对象模型)解析器将整个XML文档读入内存,并创建一个文档树,程序可以遍历该文档树并操作其中的节点。DOM解析器适用于文档相对较小的情况。_xml文件解析

j2ee与数据库有关的学习_j2ee java service query 数据库-程序员宅基地

文章浏览阅读234次。什么是JDBCJDBC的作用JDBC的编程步骤_j2ee java service query 数据库

STM32CUBEIDE USB下载总是连接不上 总是USBD_BUSY_if(usbdevcdc->cdctx.state != usbd_cdc_xfer_idle)-程序员宅基地

文章浏览阅读3.7k次,点赞4次,收藏29次。开发的时候总是在调用这个函数的时候发现 //总是会卡在return USBD_BUSY; uint8_t CDC_Transmit_HS(uint8_t* Buf, uint16_t Len){ uint8_t result = USBD_OK; /* USER CODE BEGIN 12 */ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_..._if(usbdevcdc->cdctx.state != usbd_cdc_xfer_idle)

java分布式系统架构图,2022吊打面试官系列_java技术搭建的大型分布式异构系统-程序员宅基地

文章浏览阅读2.3k次。前言如果你不能拼爹,或者不想拼爹,最好的方法是拼实力。合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。所以,你必须要从基层做起。当然,所谓的基层,并不是端茶倒水,但多一些体验,总是无害的。前两年的时间,应当主要打好基础的累积,认清职业现状和社会经济发展趋势,适应工作后的生活,对心灵浮躁的洗涤。这一阶段最大的敌人是自身的态度,切忌不可眼高手低,牢记一句话——“心比天高,命比纸薄。”脚踏实地,一步一个脚印,为未来做好铺垫。一、分布式架构学习路线图据统计,人的阅读时间在20分钟以内是_java技术搭建的大型分布式异构系统

推荐文章

热门文章

相关标签