TCP 数据传输的拆包和粘包了解吗?

前言:

上一篇我们了解了什么是 TCP 协议,以及 TCP 协议 3 次握手 4次挥手的原因,本篇来分享一下 TCP 数据的传输过程的拆包和粘包,以及 TCP 数据传输过程中的一些细节。

计算机网络往期文章

TCP 为什么是 3 次握手 4 次挥手?

TCP 数据是如何发送接收的?

我们知道 TCP 是传输层协议,TCP 协议传输数据有发送和接收的过程,我们知道 TCP 数据传输的时候是将一个完整的数据拆分成一段一段发送的,收到数据之后有会将一段一段的数据合并起来,还原成完整的数据。

TCP 为什么要把完整数据进行拆分发送,然后接收到之后又要合并?

TCP 把数据拆分发送有一下原因:

  • 稳定性:一次发送的数据包越大传输的稳定性越差,越容易出错,把完整数据拆分成一小段一小段发送,可以提升数据传输的稳定性。
  • 提升效率:数据传输时候,有时候是可以并行发送的,把数据拆分成一段一段的,就可以利用并行发送的能力,提升数据传输效率。
  • 内存页限制:我们知道内存的最小分配单位是页,一页的大小默认是 4K,如果一次性传输超过一个内存页大小的数据,会存在页置换的问题,会造成一定的性能损失。
  • 缓冲区问题:我们知道数据传输和接收的时候都存在缓冲区,缓冲区是内存中开辟的一块内存区域,大小也是有限制的,缓冲区的作用是用来缓冲网卡暂时处理不过来的请求,这些请求在缓冲区排队,如果一次发送的数据量太大,那缓冲区就会被迅速占满,也就失去了缓冲的意义。

总而言之就是一次传输太大的数据包就是不合适的,从软件开发的思想来说一次处理大量的数据也是不合适的。

TCP 数据传输的拆包和粘包是什么意思?

  • 拆包:像我们上面说的把一个大的数据包拆分成一小段一小段的发送,接收之后在再将这些数据包组合到一起的过程叫做拆包。
  • 粘包:粘包从字面意思理解就是和拆包相反,其本质意思也确实如此,我们发送到一个接收端的数据量太小,为了防止多次发送导致的资源占用,TCP 协议会在发送的时候,对数据进行合并处理,将多个小的数据包合并成一个 TCP 段来发送,在数据接收端接收到数据后,在进行数据拆分还原,这个过程叫做粘包。

通过同拆包和粘包的解释,我们发现所谓的“拆”、“粘”都是已发送端的操作来定义的。

TCP SEGMENT(TCP 报文段)

上面在解释粘包的时候提到了将数据合并成一个 TCP SEGMENT 进行数据传输,下面我们来剖析一下什么是 TCP SEGMENT。

TCP SEGMENT 组成示意图如下:

在这里插入图片描述

对 TCP SEGMENT 组成部分逐个剖析如下:

  • 源端口号:发送端端口号,字段长 16 位占用 2字节。
  • 目标端口号:接收端端口号,字段长 16 位占用 2字节。
  • 序列号(sequence number):发送数据的第一个字节的编号,字段长度为 32 位占用 4字节。
  • 确认应答号(acknowledge number):期望收到下一个报文段的第一个数据字节的序列号,该字段段长度也是 32 位占用 4字节。
  • 数据偏移量(data offset):表示的是 TCP 首部的长度,字段长 4位。
  • 保留位(reserved):为 TCP 扩展使用,字段长 4位。
  • 控制位(control flag):描述了 TCP 的一些能力,该字段长 8位,对应 8个字段,如下:

ECE(ECN-Echo):为 1 时会通知通信对方,从对方到这边的网络有拥塞。
URG:为1时,表示有紧急数据需要处理,发送方会将紧急数据插入到报文段的最前面,需要与 TCP 首部紧急指针(urgent pointer)配合使用。
ACK:ACK 为 1 时,确认好字段才有效,当 ACK 为 0 时,确认号无效,是 TCP 传输可靠性的一种保障。
PSH:数据推送的意思,为 1 时,发送方会立即创建一个报文段发送出去,接收方在收到报文段后,就立刻交付给接收方应用进程,而不用等到整个缓存填满了再交付。
RST:为 1时,表示 TCP 连接出现严重问题,必须释放连接,然后重新建立连接,RST 为 1 也可以用来拒绝非法的报文段。
SYN:为 1 时,表明这是一个连接请求。
FIN:用来关闭连接,当 FIN 为 1 时,表明此报文段的发送方的数据已发送完毕,请求关闭 TCP 连接。

  • 窗口大小(window size):占 2字节,表示发送方的接收方允许发送方发送的数据量,发送方的发送窗口大小也是依据这个窗口,接收方的数据缓存空间是有限的,因此窗口大小页是动态变化的。
  • 校验和(checksum):占用 2个字节,校验 TCP 首部和数据两部分,用于校验 TCP 段有没有损坏。
  • 紧急指针(urgent pointer):占用 2个字节,紧急指针仅当 URG=1 时才有意义,指向最后一个紧急数据的序号(Sequence Number),因为紧急数据页可能是连续的很多个段,所以需要提前告诉接收方进行准备。
  • TCP 选项(TCP option):option 中存储了一些可选字段,比如 MSS。
  • 填充(padding):就是我们常说的对其填充,不足 4 字节的整数倍时候,就进行填充。

什么是 MSS?

MSS 的全称是 Maximun Segment Size,翻译过来就是最大分段大小,MSS 控制了 TCP 段的大小,它是一个协商字段,需要发送方接收方协商,然后双方都要遵循的标准,因此需要双方协商决定。MSS 的大小涉及发送、接收缓冲区的大小设置,双方实际发送接收到包的大小,也会影响到拆包和粘包,因此需要慎重设置。

假设 MSS 设置过大有什么后果?

我们前面提到的拆包,就是因为数据过大才需要进行拆包,如果 MSS 设置过大,那拆包还有什么意义呢?对性能的损耗、内存使用的损耗等问题都出来了。

那 MSS 设置过小又有什么问题?

MSS 如果拆分的过小,会影响数据传输性能,被拆分每一份数据都有一个 TCP 首部,MSS 过小 TCP 首部的数据占比会大幅上升,这会造成严重的传输资源浪费。

如有不正确的地方欢迎各位指出纠正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值