简介

   TCP 是一个’流’协议,所谓流,就是没有界限的一串数据. 大家可以想想河里的流水,是连成一片的.期间并没有分界线, TCP 底层并不了解上层业务数据的具体含义 ,它会根据 TCP 缓冲区的实际情况进行包得划分,所以在业务上认为,一个完整的包可能会被 TCP 拆分成多个包进行发送 . 也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的 TCP 拆包和粘包.
 

TCP 粘包/拆包问题说明

     我们可以通过图解对 TCP 粘包和拆包进行说明.粘包问题示例图:
 
 
假设客户端分别发送了两个数据包 D1,D2 给服务端, 由于服务端一次读到的字节数是不确定的.故可能存在以下4种情况.
  1. 服务端分两次读取了两个独立的数据包. 分别是 D1,D2 ,没有粘包和拆包;
  2. 服务器一次收到两个数据包,D1和 D2粘在一起,被称为 TCP 的粘包;
  3. 服务器分两次读到两个数据包,第一次读到了完整的 D1包和D2的部分内容,第二次读取到了 D2包得剩余内容,这被称为 TCP 的拆包.
  4. 服务器分两次读到两个数据包,第一次读取到了 D1包得部分内容,第二次读取到了 D1包得剩余内容 D1_2和 D2包的整包.
 
     如果此时服务端的 TCP 接收滑窗非常小, 而且数据包D1和 D2比较大,很有可能出现第五种可能,即 服务端分多次才能将 D1和 D2包接收完全. 期间发生多次拆包.
 

TCP 粘包/拆包发生的原因

     
     问题产生的原因有三个,分别如下.
  1. 应用程序 write 写入的字节大小大于套接字接口发送缓冲区大小;
  2. 进行 MSS 大小的 TCP 分段;
  3. 以太网帧的 payload 大于 MTU 进行 IP 分片;
 
粘包问题的解决策略
     由于底层的 TCP 无法理解上层业务数据,所以在底层是无法保证数据包不被拆分和重组的 , 这个问题只能通过上层的应用协议栈设计来解决,根据业界主流的协议的解决方案, 可以归纳如下:
  1. 消息定长, 例如每个报文的大小固定长度200字节,如果不够,空位补齐空格;
  2. 在包尾部添加回车换行符进行分割, 例如 FTP 协议;
  3. 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息具体长度)的字段,通常设计思路为消息头的第一个字段使用 int32 来表示消息的总长度;
  4. 更复杂的应用协议层;
 
 
 
 
 

TCP 粘包/拆包问题的更多相关文章

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

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

  2. TCP粘包/拆包问题

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. linux下快速删除大量文件

    昨天遇到一个问题,在Linux中有一个文件夹里面含有大量的Cache文件(夹),数量级可能在百万级别,使用rm -rf ./* 删除时间慢到不可接受.Google了一下,查到了一种方法,试用了下确实比 ...

  2. 2014第五届蓝桥杯试题C/C++程序设计B组——切面条

    题目描述:标题:切面条 一根高筋拉面,中间切一刀,可以得到2根面条. 如果先对折1次,中间切一刀,可以得到3根面条. 如果连续对折2次,中间切一刀,可以得到5根面条. 那么,连续对折10次,中间切一刀 ...

  3. Sublime Text 2 安装与使用SFTP插件

    http://wbond.net/sublime_packages/sftp/usage http://www.360doc.com/content/13/0603/15/9437165_290170 ...

  4. 2)Java中的==和equals

    Java中的==和equals   1.如果比较对象是值变量:只用==   2.如果比较对象是引用型变量:      ==:比较两个引用是不是指向同一个对象实例.      equals:       ...

  5. C# 处理csv格式的Excel文件代码

    public class CSVFileHelper { /// <summary> /// 将DataTable中数据写入到CSV文件中 /// </summary> /// ...

  6. 如何让Advanced Installer卸载软件时保留一些文件

    http://www.advancedinstaller.com/user-guide/qa-keep-file.html You need to modify some of the resourc ...

  7. mousewheel滚轮事件

    原生的滚轮事件:火狐与其他浏览器使用了不同的事件 /* * 滚轮事件只有firefox比较特殊,使用DOMMouseScroll; 其他浏览器使用mousewheel; * */ // firefox ...

  8. IOS之表视图添加搜索栏

    下面是我们要实现的效果.本效果是在上一篇自定义表视图的基础上进行更改的.     1.将Search bar and search display拖动到ViewController中.不要添加Sear ...

  9. [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)

    介绍完了服务器,这篇我们就要介绍重点了,写我们自己的IOS客户端程序 先看一下我们完成的效果图 首先下载xmppframework这个框架,下载 点ZIP下载 接下来,用Xcode新建一个工程 将以下 ...

  10. centos6.3编译安装Apache2.4.3+PHP5.4.8+Mysql5.5.8

    以虚拟机VirtualBox 版本是4.1.20(内存设置为512M,centos安装是文本模式下安装),全新以最小化包安装了32位的 CentOS6.3系统,作为本地web环境,上次讲了在windo ...