TCP粘包和拆包问题
问题产生
一个完整的业务可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这个就是TCP的拆包和封包问题。
下面可以看一张图,是客户端向服务端发送包:
1. 第一种情况,Data1和Data2都分开发送到了Server端,没有产生粘包和拆包的情况。
2. 第二种情况,Data1和Data2数据粘在了一起,打成了一个大的包发送到Server端,这个情况就是粘包。
3. 第三种情况,Data2被分离成Data2_1和Data2_2,并且Data2_1在Data1之前到达了服务端,这种情况就产生了拆包。
由于网络的复杂性,可能数据会被分离成N多个复杂的拆包/粘包的情况,所以在做TCP服务器的时候就需要首先解决拆包/粘包的问题。
TCP粘包和拆包产生的原因
1. 应用程序写入数据的字节大小大于套接字发送缓冲区的大小
2. 进行MSS大小的TCP分段。MSS是最大报文段长度的缩写。MSS是TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所以MSS并不是TCP报文段的最大长度,而是:MSS=TCP报文段长度-TCP首部长度
3. 以太网的payload大于MTU进行IP分片。MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。如果IP层有一个数据包要传,而且数据的长度比链路层的MTU大,那么IP层就会进行分片,把数据包分成托干片,让每一片都不超过MTU。注意,IP分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
TCP粘包和拆包的解决策略
1. 消息定长。例如100字节。
2. 在包尾部增加回车或者空格符等特殊字符进行分割,典型的如FTP协议
3. 将消息分为消息头和消息尾。
4. 其它复杂的协议,如RTMP协议等。
TCP粘包和拆包问题的更多相关文章
- netty 解决TCP粘包与拆包问题(一)
1.什么是TCP粘包与拆包 首先TCP是一个"流"协议,犹如河中水一样连成一片,没有严格的分界线.当我们在发送数据的时候就会出现多发送与少发送问题,也就是TCP粘包与拆包.得不到我 ...
- tcp粘包和拆包的处理方案
随着智能硬件越来越流行,很多后端开发人员都有可能接触到socket编程.而很多情况下,服务器与端上需要保证数据的有序,稳定到达,自然而然就会选择基于tcp/ip协议的socekt开发.开发过程中,经常 ...
- 【Netty】TCP粘包和拆包
一.前言 前面已经基本上讲解完了Netty的主要内容,现在来学习Netty中的一些可能存在的问题,如TCP粘包和拆包. 二.粘包和拆包 对于TCP协议而言,当底层发送消息和接受消息时,都需要考虑TCP ...
- TCP粘包,拆包及解决方法
在进行Java NIO学习时,发现,如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况,这就是TCP协议中经常会遇到的粘包以及拆包的问题.我们都知道TCP属于传输 ...
- TCP粘包、拆包
TCP粘包.拆包 熟悉tcp编程的可能都知道,无论是服务端还是客户端,当我们读取或发送数据的时候,都需要考虑TCP底层的粘包/拆包机制. TCP是一个“流”协议,所谓流就是没有界限的遗传数据.可以想象 ...
- 【游戏开发】网络编程之浅谈TCP粘包、拆包问题及其解决方案
引子 现如今手游开发中网络编程是必不可少的重要一环,如果使用的是TCP协议的话,那么不可避免的就会遇见TCP粘包和拆包的问题,马三觉得haifeiWu博主的 TCP 粘包问题浅析及其解决方案 这篇博客 ...
- 关于TCP粘包和拆包的终极解答
关于TCP粘包和拆包的终极解答 程序员行业有一些奇怪的错误的观点(误解),这些误解非常之流行,而且持有这些错误观点的人经常言之凿凿,打死也不相信自己有错,实在让人啼笑皆非.究其原因,还是因为这些错误观 ...
- netty 解决TCP粘包与拆包问题(二)
TCP以流的方式进行数据传输,上层应用协议为了对消息的区分,采用了以下几种方法. 1.消息固定长度 2.第一篇讲的回车换行符形式 3.以特殊字符作为消息结束符的形式 4.通过消息头中定义长度字段来标识 ...
- TCP粘包的拆包处理
因为TCP是流式处理的,所以包没有边界,必须设计一个包头,里面表示包的长度(一般用字节表示),根据这个来逐个拆包.如果对于发送/接收频率不高的话,一般也就不做拆包处理了,因为不大可能有粘包现象. 以下 ...
随机推荐
- [整理]vimtutor章节小结
第一讲小结 1. 光标在屏幕文本中的移动既可以用箭头键,也可以使用 hjkl 字母键. h (左移) j (下行) k (上行) l (右移) 2. 欲进入 Vim 编辑器(从命令行提示符),请输入: ...
- [].slice.call(arguments,1)
[转] 前言 今天偶然翻资料看到一个叫做软绑定的函数,用来确定this的; 原代码 if(!Function.prototype.softBind){ Function.prototype.softB ...
- assert断言
https://www.cnblogs.com/ggzss/archive/2011/08/18/2145017.html assert是一个宏定义,其作用是如果它的条件返回错误,则终止程序执行,原型 ...
- Android自定义安全键盘
在银行APP里经常要自定义键盘,例如实现下面这样的效果 首先在xml文件里定义键盘 <Keyboard xmlns:android="http://schemas.andr ...
- hdu_1025(LIS Nlog(N)算法)
题意:自己慢慢读吧.大概就是道路两边建路,给出建路需求,要求两条路不能有交叉,问最多可以建多少条路. 题解:一看数据范围500000,应该是dp,再画个图模拟一下,发现实质就是求最长上升子序列,很自然 ...
- 解决vi编辑器不能使用方向键和退格键问题的两种方法
方法1.使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多字母? 在Ubuntu中,进入vi命令的编辑模式,发现按方向键不能移动光标,而是会输出ABCD,以及退格键也不能正常删除字符.这是由于 ...
- 安装myeclipse后,打开时弹出:“该站点安全证书的吊销证书不可用”,怎样解决?
1.当弹出"该站点安全证书的吊销信息不可用.是否继续?"的对话框时,点击"查看证书",切换到"详细信息"TAB页,找到其"CRL分 ...
- Spring框架学习笔记(1)——HelloWorld
1.创建一个新的项目,并添加Spring框架 2.创建HelloWorld.java package com.broadtext.beans.helloworld; public class Hell ...
- css3渐变之线性渐变
css3定义了两种类型的渐变,即线性渐变和径向渐变.这里我要说的是线性渐变. 为了创建一个线性渐变,你必须至少定义两种颜色结点.颜色结点即你想要呈现平稳过渡的颜色.同时,你也可以设置一个起点和一个方向 ...
- 用AngularJS实现对表格的增删改查(仅限前端)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...