TCP粘包、拆包

熟悉tcp编程的可能都知道,无论是服务端还是客户端,当我们读取或发送数据的时候,都需要考虑TCP底层的粘包/拆包机制。

TCP是一个“流”协议,所谓流就是没有界限的遗传数据。可以想象下,如果河里的水就是数据,他们是连成一片的,没有分界线。TCP底层并不了解上层的业务数据具体的含义,它会根据TCP缓冲区的实际情况进行包的划分,也就是说,在业务上,我们一个完整的包可能会被TCP分成多个包进行发送,也可能把多个小包装封装成一个大的数据包发送出去,这就是所谓的TCP粘包、拆包问题。

分析TCP粘包、拆包问题产生的原因“

  1、应用程序write写入的字节大小大于套接口发送缓冲区的大小

  2、进行MSS大小的TCP分段

  3、以太网帧的payload大于MTU进行IP分片

下面看一下粘包的现象:

Client端连续发送3次数据,下面看一下Server端的打印结果:

可以看到,Server端接收到的结果是连接在一起的,

这就是粘包的现象。

TCP粘包、拆包问题解决方案

粘包拆包问题的解决方案,根据业界的主流协议,有三种方案:

  1消息定长,例如每个报文的大小固定为200个字符,如果不够,空位补空格;

  2在包尾部增加特殊字符进行分割,例如加回车等;

  3讲消息分为消息头和消息体,在消息头中包含表示消息总长度的字段。然后进行业务逻辑的处理

netty提供了一些基础累:

1分隔符类DelimiterBasedFrameDecoder(自定义分隔符)

2FixedLengthFrameDecoder(定长)

下面看一下如何使用自定义分隔符进行拆包的,

在Server端,

接收到Client端传来的buf数据,然后通过 DelimiterBasedFrameDecoder 把数据解析成String类型的数据,看一下下面的相关实现:

我这边是通过“$_”这个字符串作为分隔符,下面看一下ServerHandler里面的响应代码:

因为在前面已经转换成String类型了,这边只是确保一下类型,进行了一下强转,这边向客户端发送的数据要是原先的buf数据,不然客户端没办法去解析,

同样的看一下Client端的程序,Client端的程序与Server端的程序类似:

看一下ClientHandler代码,ClientHandler端就把server端响应的代码进行了打印:

看一下运行结果,和原先没有使用分隔F的进行一下对比,看看有什么区别:

Server端接收到3条Client端发送的数据,没有发生粘包的现象。Client端也收到Server端响应的3条数据。

这是第一种处理TCP拆包粘包的处理方式,下面我们看一下第二种处理方式:

只需要把使用的类替换掉,并定义字节的长度,不过需要自己传输的字符串自己添加空格,如果不添加,或者设置的字节太短,都会出现粘包的现象。

TCP粘包、拆包的更多相关文章

  1. Netty(三)TCP粘包拆包处理

    tcp是一个“流”的协议,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题. 粘包.拆包问题说明 假设客户端分别发送数据包D1和D ...

  2. TCP粘包/拆包问题

    无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. TCP粘包/拆包 TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想想河 ...

  3. TCP 粘包/拆包问题

    简介    TCP 是一个’流’协议,所谓流,就是没有界限的一串数据. 大家可以想想河里的流水,是连成一片的.期间并没有分界线, TCP 底层并不了解上层业务数据的具体含义 ,它会根据 TCP 缓冲区 ...

  4. TCP粘包/拆包问题的解决

    TCP粘包拆包问题 一个完整的包可能被TCP拆分成多个包,或多个小包封装成一个大的数据包发送. 解决策略 消息定长,如果不够,空位补空格 在包尾增加回车换行符进行分割,例如FTP协议 将消息分为消息头 ...

  5. Netty(二)——TCP粘包/拆包

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7814644.html 前面讲到:Netty(一)--Netty入门程序 主要内容: TCP粘包/拆包的基础知 ...

  6. 第四章 TCP粘包/拆包问题的解决之道---4.1---

    4.1 TCP粘包/拆包 TCP是一个“流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可 ...

  7. Java网络编程基础之TCP粘包拆包

    TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想象河里的流水,他们是连成一片的,其间并没有分界线.TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实 ...

  8. TCP粘包/拆包 ByteBuf和channel 如果没有Netty? 传统的多线程服务器,这个也是Apache处理请求的模式

    通俗地讲,Netty 能做什么? - 知乎 https://www.zhihu.com/question/24322387 谢邀.netty是一套在java NIO的基础上封装的便于用户开发网络应用程 ...

  9. netty之==TCP粘包/拆包问题解决之道(一)

    一.TCP粘包/拆包是什么 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在 ...

  10. Netty使用LineBasedFrameDecoder解决TCP粘包/拆包

    TCP粘包/拆包 TCP是个”流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TC ...

随机推荐

  1. android平台yuv缩放相关<转>

    Android的视频相关的开发,大概一直是整个Android生态,以及Android API中,最为分裂以及兼容性问题最为突出的一部分.摄像头,以及视频编码相关的API,Google一直对这方面的控制 ...

  2. linux环境运行java项目并有外部引用jar

    eclipse目录结构: linux目录结构: lib目录结构: 其中除了IMT_ENCODING_DSP.jar其余的都是外部引用的jar IMT_ENCODING_DSP.jar是java项目打包 ...

  3. Servlet基本_WAR、デプロイ

    1.WAR.パッケージングWARはWeb Aplication Resourcesの略で.Webアプリに必要なファイルを1つのファイルにまとめて圧縮したものです.(日本では「わー」と発音の人が多い)W ...

  4. Java相关文章

    servlet/filter/listener/interceptor区别与联系 web.xml配置详解 在Eclipse中使用JUnit4进行单元测试(初级篇) 单点登录原理与简单实现 spring ...

  5. Object-c 调用unity的 UIViewController和UnitySendMessage

    .mm文件中实现 #import <UIKit/UIKit.h> extern UIViewController *UnityGetGLViewController(); extern & ...

  6. 剑指OFFER例题——从尾到头打印链表

    /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int val) { * this.val ...

  7. Jquery select chosen 插件注意点

    <select style="width:200px;" name="carId" data-placeholder="选择车辆牌照" ...

  8. 趣味编程:静夜思(Swift版)

    func verticalWriting(txt:String, offset:Int) { Dictionary(grouping: txt.enumerated(), by: {$0.0 % of ...

  9. SSL和TLS协议的区别

    SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层.SSL通过互相认证.使用数字签名确保完整性.使用加密确保私密性,以实现客户 ...

  10. 安装vue CLI后, 出现安装权限问题

    问题:安装vue CLI后,出现:npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/usr/l ...