TCP 粘包拆包
粘包问题
在 TCP 这种字节流协议上做应用层分包
是网络编程的基本需求。分包指的是在发生一个消息(message)或一帧(frame)数据时,通过一定的处理,让接收方能从字节流中识别并截取(还原)出一个个消息。因此,“粘包问题”是个伪命题
短连接分包
对于短连接的 TCP 服务,分包不是一个问题,只要发送方主动关闭连接,就表示一个消息发送完毕,接收方 read() 返回0,从而知道消息的结尾
TCP 发送机制
为了提高 TCP 的传输效率,TCP 有一套自己的发送机制
- TCP 维持一个变量,它等于
最大报文段长度 MSS
。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去 - 由发送方的应用进程指明要求发送报文段,即 TCP 支持的
推送(push)
操作 - 发送方的一个计时器期限到了,这时把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去
长连接分包
对于长连接的 TCP 服务,分包有四种方法
- 消息长度固定
- 使用特殊的字符或字符串作为消息的边界,例如 HTTP 协议的 headers 以“rn”为字段的分隔符
- 在每条消息的头部加一个长度字段,这恐怕是最常见的做法
- 利用消息本身的格式来分包,例如 XML 格式的消息中
<root>
...</root>
的配对,或者 JSON 格式中的 { ... } 的配对。解析这种消息格式通常会用到状态机(state machine)
复杂的分包
假如消息格式非常简单,“消息”本身是一个字符串,每条消息有一个4字节的头部,以网络序存放字符串的长度。消息直接没有间隙,字符串也不要求以 '0' 结尾
发送两条消息“hello”和“smartboy”,打包后的字节流共有21字节
0x00, 0x00, 0x00, 0x05, 'h', 'e', 'l', 'l', 'o', 0x00, 0x00, 0x00, 0x08, 's', 'm', 'a', 'r', 't', 'b', 'o', 'y'
假设数据最终都全部到达,数据解析逻辑至少能正确处理以下各种数据到达的次序
- 一个字节一个字节到达
- 数据分两次到达,第一次收到2个字节,不足消息的长度字段
- 数据分两次到达,第一次收到4个字节,刚好够长度字段,但是没有 body
- 数据分两次到达,第一次收到8个字节,长度完整,但 body 不完整
- 数据分两次到达,第一次收到9个字节,长度完整,但 body 也完整
- 数据分两次到达,第一次收到10个字节,第一条消息的长度完整、body 也完整,第二条消息长度不完整
- 请自行移动和增加分割点,一共有超过 100 万种可能(221-1)
- 数据一次就全部到达
《TCP粘包拆包》 原文链接:https://blog.maplemark.cn/2019/04/tcp粘包拆包.html?utm=alc
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Cglib 和 Mica Bean copy 生成字节码对比
1. 前言 距离上上篇【mica cglib 增强——【01】cglib bean copy 介绍】 已经过去一个月八一天。 距离上一篇【Java Bean Copy 性能大比拼】 已过去一个月零一天。 督促自己早日完成整个系列的文章,今天我将带领大家从字节码的层面来分析。 注:对于java 字节码感兴趣的朋友也可以阅读 《Java虚拟机规范》,Oracle 官方也有英文原版的 pdf可供下载。 2. Bean 模型 我们列举2个模型 User 和 UserVo,注意:birthday 字段类型不一样(敲黑板)。 2.1 User @Data public class User { private Integer id; private String name; private Integer age; private LocalDateTime birthday; } 2.2 UserVo @Data public class UserVo { private String name; private Integer age; private String birthday; } 3...
- 下一篇
Aliyun Linux 2 软件更新 - 2019.05.01
1. 添加下列新包: Dragonfly-0.3.0-3.al7: 阿里巴巴开源的基于P2P镜像及文件分发系统,官网:https://d7y.io/ ; tengine-2.3.0-1.al7: 在 Nginx 基础上加入阿里巴巴定制功能的 Web 服务器,官网:http://tengine.taobao.org/ ; luajit-2.0.4-3.1.al7: Just-In-Time Compiler for Lua, Tengine 依赖包; jemalloc-4.0.4-1.1.al7: General-purpose scalable concurrent malloc implementation, Tengine 依赖包; ossfs-1.80.5-1.al7: 支持 Aliyun OSS bucket 挂载到本地文件系统中的
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8