那年那夏那些不太懂的TCP3

粘包、拆包

粘包、拆包指的是接收端接收到的报文段的形式,由于TCP是基于流的,而流是没有消息边界的,也就是接收端收到传输层的内容,不知道代表的是一个报文,还是多个报文,或者是不足一个报文。仅靠TCP本身是无法解决这个问题的,这是就需要应用层协议来帮忙了。通信的双方约定好使用的应用层协议,那么在接收端收到发送端传来的消息后,就按照约定好的应用层协议进行解析,这样就不会出现一些乱码的错误了。那么粘包、拆包问题是如何发生的? 具体的解决方案又是怎样的? 待我慢慢揭晓 ( -_-

什么是粘包、拆包

比如发送端要发送两个完整的数据DATA1和DATA2, 具体内容为 , DATA1:ABCD DATA2: EFGH , 那么接收端收到的有可能就是 ABCD EFGH(想要的结果), ABC DEFGH (DATA1拆包、DATA2粘包), ABCDE FGH(DATA1粘包、DATA2拆包), ABCDEFGH (粘包), 等等。为什么会这个样子?因为。。。

为什么会发生粘包、拆包
  1. MSS: MSS是TCP payload中的最大长度,即TCP在一次传输中携带的最大数据长度。如果应用层要传输的数据大于了MSS, 就需要进行拆开发送,使得每一个报文段的长度的都小于等于MSS. 这就发生了拆包。
  2. Nagle算法: Nagle算法规定在任意时刻,最多只能有一个未被确认的小段(小指的是小于MSS),也就是发送端发送完一个小于MSS的报文段后,要等待接收端的确认应答才能继续发送小于MSS的报文段,在这等待的过程中,应用层可能又有了要发送的数据,于是有存放到了发送的发送窗口中,多个数据堆积在一起,就发生了粘包。
  3. 滑动窗口。接收端在每次发送给发送端ACK的时候,都会携带窗口大小的信息,(窗口大小指的就是接收端的接收窗口的大小,该值在TCP的头部)。有了滑动窗口后,发送端就可以连续多次发送报文段,在这过程中即便没有ACK确认。在某时刻,要发送的数据的长度大于接收窗口的窗口大小时,就需要拆分数据进行发送,会发生拆包现象。
怎么解决拆包、粘包问题

传输层是无能为力了,因为传输层只管传输数据,并不管传输的是什么数据,数据表示的是什么意思,它不知道,也不想知道,因为无需知道。数据本无意义,不过是应用层赋予了它意义。那么好了,既然应用层知道数据是什么意思,那么就应该知道到那个地方就是一个完整的数据,比如:今天天气不错我想一个人去西藏旅行。 如果天气不错后面不加个逗号“,”,我们又怎么知道它是什么意思呢(不要说知道,因为你的知道其实也是在心中在它后面给加了一个逗号,是也不是 ( -_- )。正所谓,古人的,句读之不知,惑之不解,或师焉,或不焉。可见,句读是很重要的,也就是断句很重要,也就是应用层要知道到个地方是一个完成的报文,so, how to do it?

  • 固定长度。 双方协商好每个数据的长度是多少,比如10个字节,那么接收端的应用层就按照10个字节为一个完成的数据,来进行解析。
  • 特殊字符。可以在数据的结尾处或者开始 处加上某些特殊字符,接收端读取到这些字符后,就知道一个完整的数据结束了。比如在每个数据的后面加上\r\n, 这样,读取到\r\n后,就知道一个完整的数据结束了,后面的是另一个数据了。
  • 数据头加数据体,即每个数据都是由数据头和数据体构成的,如果约定数据的头四个字节用作数据头,表示的是数据体的长度是多少,那么就可以根据数据头不的数字来解析对应的数据体长度。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值