Java网络编程基础之TCP粘包拆包
TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想象河里的流水,他们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送。这就是TCP所谓的拆包和粘包的问题。
一、TCP粘包/拆包问题说明
我们可以通过图解对TCP粘包和拆包问题进行说明,粘包问题如图。

假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下4中情况。
- 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包。
- 服务端一次接收到了两个数据包,D1和D2粘在一起,被称为TCP粘包
- 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包。
- 服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余内容D1_2和D2包的整包。
如果此时服务端TCP接收滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种可能,即服务端分多次才能将D1和D2包接收完全,期间发生多次拆包。
二、TCP粘包/拆包发生的原因
问题产生的原因有三个,分别如下。
- 应用程序write写入的字节大小大于套接口发送缓冲区大小。
- 进行MSS大小的TCP分段。
- 以太网帧的payload大于MTU进行IP分片。
三、粘包问题的解决策略
由于底层的TCP无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,可以归纳如下。
- 消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格
- 在包尾增加回车换行符进行分割,例如FTP协议
- 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段,通常涉及思路为消息头的第一个字段使用int32来表示消息的总长度
- 更复杂的应用层协议。
Java网络编程基础之TCP粘包拆包的更多相关文章
- python网络编程基础之socket粘包现象
粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- java网络编程socket\server\TCP笔记(转)
java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04| 分类: Socket | 标签:java |举报|字号 订阅 1 TCP的开销 a ...
- Java网络编程基础(Netty预备知识)
今天在家休息,闲来无事,写篇博客,陶冶下情操~~~ =================我是分割线================ 最近在重新学习Java网络编程基础,以便后续进行Netty的学习. 整 ...
- 用java网络编程中的TCP方式上传文本文件及出现的小问题
自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文 ...
- TCP粘包/拆包 ByteBuf和channel 如果没有Netty? 传统的多线程服务器,这个也是Apache处理请求的模式
通俗地讲,Netty 能做什么? - 知乎 https://www.zhihu.com/question/24322387 谢邀.netty是一套在java NIO的基础上封装的便于用户开发网络应用程 ...
- Netty(二)——TCP粘包/拆包
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7814644.html 前面讲到:Netty(一)--Netty入门程序 主要内容: TCP粘包/拆包的基础知 ...
- 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)
一.粘包/拆包概念 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在业务上认 ...
- Netty(三)TCP粘包拆包处理
tcp是一个“流”的协议,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题. 粘包.拆包问题说明 假设客户端分别发送数据包D1和D ...
随机推荐
- POJ1789 Truck History 2017-04-13 12:02 33人阅读 评论(0) 收藏
Truck History Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27335 Accepted: 10634 D ...
- Python入门基础学习 三
Python入门基础学习 三 数据类型 Python区分整型和浮点型依靠的是小数点,有小数点就是浮点型. e记法:e就是10的意思,是一种科学的计数法,15000=1.5e4 布尔类型是一种特殊的整形 ...
- 报表导出jxls的使用笔记
基于poi的jxls工具的使用:1.依赖: <dependency> <groupId>org.jxls</groupId> <artifactId>j ...
- ISO in CSS content
Name Numeric Description Hex ISO in CSS content Octal no-break space %A0 p:before { content: ...
- 纸壳CMS3.0中的规则引擎,表达式计算
纸壳CMS3.0中的规则引擎,用于计算通用表达试结果.通常业务逻辑总是复杂多变的,使用这个规则引擎可以灵活的修改计算表达式. IRuleManager IRuleManager,是使用规则引擎的主要接 ...
- .NetCore分布式部署中的DataProtection密钥安全性
在.NetCore中默认使用DataProtection来保护数据,例如Cooike等.一般情况下DataProtection生成的密钥会被加密后存储,例如默认的文件存储 可以看到使用了Windows ...
- 使用WebService调用第三方服务
场景 某个系统服务由第三方提供,我方要使用到这个这个服务,就可以使用WebService的方式. 什么是WebService 关于什么WebService,官方是这么解释的: Web service是 ...
- soundPool的使用
SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100); HashMap<Integer, Integer& ...
- collections模块—— Counter
ounter目的是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value.计数值可以是任意的Interger(包括0和负数).Counter类和 ...
- 【OCP题库】最新CUUG OCP 12c 071考试题库(67题)
67.(25-8)choose the best answer: View the Exhibit and examine the structure of CUSTOMERS table. Eval ...