一、TCP使用场景

TCP 协议提供了可靠性常用的使用场景: HTTP 协议、消息队列、存储、缓存,都需要用到 TCP 协议。

二、TCP 的拆包和粘包

TCP 是一个传输层协议。TCP 发送数据的时候,往往不会将数据一次性发送,像下图这样:
image.png

而是将数据拆分成很多个部分,然后再逐个发送。像下图这样:image.png

在传输层封包不能太大:

  • 会将数据拆分成不超过缓冲区大小的一个个部分
  • 每个部分有一个独特的名词,叫作 TCP 段(TCP Segment)
  • 在接收数据的时候,一个个 TCP 段又被重组成原来的数据

拆包是将数据拆分成多个 TCP 段传输。
粘包是将多个数据合并成一个 TCP 段发送。

三、TCP 段

image.png

  • Source Port/Destination Port 描述的是发送端口号和目标端口号,代表发送数据的应用程序和接收数据的应用程序。比如 80 往往代表 HTTP 服务,22 往往是 SSH 服务……
  • Sequence Number 和 Achnowledgment Number 是保证可靠性的两个关键。
  • Data Offset 是一个偏移量。这个量存在的原因是 TCP Header 部分的长度是可变的,因此需要一个数值来描述数据从哪个字节开始。
  • Reserved 是很多协议设计会保留的一个区域,用于日后扩展能力。
  • URG/ACK/PSH/RST/SYN/FIN 是几个标志位,用于描述 TCP 段的行为。也就是一个 TCP 封包到底是做什么用的?

1)URG 代表这是一个紧急数据,比如远程操作的时候,用户按下了 Ctrl+C,要求终止程序,这种请求需要紧急处理。

2)ACK 代表响应,我们在“02 | 传输层协议 TCP:TCP 为什么握手是 3 次、挥手是 4 次?”讲到过,所有的消息都必须有 ACK,这是 TCP 协议确保稳定性的一环。

3)PSH 代表数据推送,也就是在传输数据的意思。

4)SYN 同步请求,也就是申请握手。

5)FIN 终止请求,也就是挥手。

以上这 5 个标志位,每个占了一个比特,可以混合使用。比如 ACK 和 SYN 同时为 1,代表同步请求和响应被合并了。这也是 TCP 协议,为什么是三次握手的原因之一。

6)Window 也是 TCP 保证稳定性并进行流量控制的工具。

7)Checksum 是校验和,用于校验 TCP 段有没有损坏。

8)Urgent Pointer 指向最后一个紧急数据的序号(Sequence Number)。它存在的原因是:有时候紧急数据是连续的很多个段,所以需要提前告诉接收方进行准备。

9)Options 中存储了一些可选字段,比如接下来我们要讨论的 MSS(Maxiumun Segment Size)。
10)Padding 存在的意义是因为 Options 的长度不固定,需要 Pading 进行对齐。

四、Sequence Number(SEQ) 和 Acknowledgement Number(ACK)

在 TCP 协议的设计当中,数据被拆分成很多个部分,部分增加了协议头。合并成为一个 TCP 段,进行传输。这个过程,我们俗称拆包。这些 TCP 段经过复杂的网络结构,由底层的 IP 协议,负责传输到目的地,然后再进行重组。

稳定性要求数据无损地传输,也就是说拆包获得数据,又需要恢复到原来的样子。而在复杂的网络环境当中,即便所有的段是顺序发出的,也不能保证它们顺序到达,因此,发出的每一个 TCP 段都需要有序号。这个序号,就是 Sequence Number(Seq)。

image.png

五、答题

TCP 协议是如何恢复数据的顺序的,TCP 拆包和粘包的作用是什么?

TCP 拆包的作用是将任务拆分处理,降低整体任务出错的概率,以及减小底层网络处理的压力。拆包过程需要保证数据经过网络的传输,又能恢复到原始的顺序。这中间,需要数学提供保证顺序的理论依据。TCP 利用(发送字节数、接收字节数)的唯一性来确定封包之间的顺序关系。粘包是为了防止数据量过小,导致大量的传输,而将多个 TCP 段合并成一个发送。