加入收藏 | 设为首页 | 会员中心 | 我要投稿 网站开发网_马鞍山站长网 (https://www.0555zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

TCP粘包、拆包与通信协议详解

发布时间:2019-10-22 02:32:31 所属栏目:教程 来源:田守枝
导读:副标题#e# 在TCP编程中,我们使用协议(protocol)来解决粘包和拆包问题。本文将详解TCP粘包和半包产生的原因,以及如何通过协议来解决粘包、拆包问题。让你知其然,知其所以然。 1 TCP粘包、拆包图解 由于TCP传输协议面向流的,没有消息保护边界。一方发送的

另外需要注意的是:对于本地回环地址(lookback)不需要走以太网,所以不受到以太网MTU=1500的限制。linux服务器上输入ifconfig命令,可以查看不同网卡的MTU大小,如下:

TCP粘包、拆包与通信协议详解

上图显示了2个网卡信息:

  • eth0需要走以太网,所以MTU是1500;
  • lo是本地回环,不需要走以太网,所以不受1500的限制。

2.3 Nagle算法

TCP/IP协议中,无论发送多少数据,总是要在数据(DATA)前面加上协议头(TCP Header+IP Header),同时,对方接收到数据,也需要发送ACK表示确认。

即使从键盘输入的一个字符,占用一个字节,可能在传输上造成41字节的包,其中包括1字节的有用信息和40字节的首部数据。这种情况转变成了4000%的消耗,这样的情况对于重负载的网络来是无法接受的。称之为"糊涂窗口综合征"。

为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

Nagle算法的规则:

  1. 如果SO_SNDBUF中的数据长度达到MSS,则允许发送;
  2. 如果该SO_SNDBUF中含有FIN,表示请求关闭连接,则先将SO_SNDBUF中的剩余数据发送,再关闭;
  3. 设置了TCP_NODELAY=true选项,则允许发送。TCP_NODELAY是取消TCP的确认延迟机制,相当于禁用了Negale 算法。正常情况下,当Server端收到数据之后,它并不会马上向client端发送ACK,而是会将ACK的发送延迟一段时间(假一般是40ms),它希望在t时间内server端会向client端发送应答数据,这样ACK就能够和应答数据一起发送,就像是应答数据捎带着ACK过去。当然,TCP确认延迟40ms并不是一直不变的,TCP连接的延迟确认时间一般初始化为最小值40ms,随后根据连接的重传超时时间(RTO)、上次收到数据包与本次接收数据包的时间间隔等参数进行不断调整。另外可以通过设置TCP_QUICKACK选项来取消确认延迟。
  4. 未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
  5. 上述条件都未满足,但发生了超时(一般为200ms),则立即发送。

3 通信协议

在了解了粘包、拆包产生的原因之后,现在来分析接收方如何对此进行区分。道理很简单,如果存在不完整的数据(拆包),则需要继续等待数据,直至可以构成一条完整的请求或者响应。

通过定义通信协议(protocol),可以解决粘包、拆包问题。协议的作用就定义传输数据的格式。这样在接受到的数据的时候:

如果粘包了,就可以根据这个格式来区分不同的包

如果拆包了,就等待数据可以构成一个完整的消息来处理。

3.1 定长协议

定长协议:顾名思义,就是指定一个报文的必须具有固定的长度。例如,我们规定每3个字节,表示一个有效报文,如果我们分4次总共发送以下9个字节:

  1. +---+----+------+----+ 
  2.   | A | BC | DEFG | HI | 
  3.   +---+----+------+----+ 

(编辑:网站开发网_马鞍山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!