关于TCP的所有你想知道的

连接导向、可靠和比特流导向

在网络层的IP协议是不可靠的。它负责将数据包从一个IP地址传递到另一个IP地址,但不对传递的数据包的交付、顺序或完整性做任何保证。这就是TCP发挥作用的地方,它确保数据传输的可靠性。

TCP具有以下三个重要特点:

  1. TCP是连接导向的。与将数据从一个服务器发送到多个服务器的UDP不同,TCP在两个特定服务器之间建立连接。
  2. TCP是可靠的。TCP保证分段的传递,无论网络条件如何。
  3. TCP是比特流导向的。使用TCP时,应用层数据被分段处理,传输层对消息的边界不可见。此外,这些分段必须按顺序处理,并且重复的分段将被丢弃。

为了标识唯一的TCP连接,我们使用以下字段,通常称为四元组:

  • 源IP地址和目标IP地址:位于IP头中,用于指导IP协议进行数据路由。
  • 源端口和目标端口:位于TCP头中,用于指示TCP协议将分段传递给哪个进程。

TCP头部的更多信息

我们已经提到了TCP头部中的源端口和目标端口。让我们进一步研究TCP头部中的其他字段,特别是在建立TCP连接时至关重要的字段。下面的图表突出显示了这些重要字段。

  • 序列号(Sequence Number):在建立新的TCP连接时,会分配一个随机的32位值作为初始序列号。接收端使用此序列号发送一个确认回复。序列号用作确保接收端对分段进行顺序处理的机制。
  • 确认号(Acknowledgment Number):接收端使用这个32位的数字来请求下一个TCP分段。这个值是序列号加一。当发送端接收到这个确认回复时,可以假定之前的所有数据都已成功接收。这个机制可以防止数据丢失。
  • 标志位(Flags):也称为控制位,标志位指示TCP消息的目的。接下来我们将在下一部分中探讨不同类型的TCP消息。控制位指示消息是用于建立连接、传输数据还是终止连接。
    • ACK:用于确认。
    • RST:用于在发生无法恢复的错误时重置连接。
    • SYN:用于初始的三次握手。序列号字段必须被设置。
    • FIN:用于终止连接。

30a07a70-c0dd-4e5e-b949-042c7368cc39_1600x934.png

在下面,我们将看到这些字段在TCP连接建立过程中的使用方式。

建立TCP连接:三次握手

让我们探讨TCP如何建立连接,这个过程被称为三次握手。下面的图表展示了三次握手的过程。

步骤0:最初,客户端和服务器都处于CLOSE状态。服务器通过在特定端口上监听传入连接来开始。

步骤1:客户端通过向服务器发送一个SYN分段来发起连接。它为序列号分配一个随机数,称为初始序列号(ISN)。将SYN控制位设置为1,将客户端转换为SYN-SENT状态。

步骤2:服务器在接收到SYN分段后,为序列号分配一个随机数,并将确认号设置为client_isn+1。然后,它将SYN和ACK控制位都设置为1,并将此分段发送回客户端。此时,服务器进入SYN-RECEIVED状态。

步骤3:客户端在接收到SYN+ACK分段后,发送一个ACK分段,并将确认号设置为server_isn+1。此时,该分段可以携带应用层数据,并且客户端进入ESTABLISHED状态。一旦服务器接收到ACK分段,它也进入ESTABLISHED状态。

值得注意的是,前两次握手不能携带数据,但第三次握手可以。在完成三次握手后,客户端和服务器可以开始交换数据。

781159a5-f60e-4c94-b815-c8abd8d73b12_1600x1442.png

TCP是可靠的,那么当一个分段丢失时会发生什么呢?

  • 如果SYN分段丢失:如果客户端在设定的时间范围内没有收到SYN+ACK,它会重新发送SYN分段多次(默认为5次)。如果仍然没有收到SYN+ACK分段,客户端会终止连接,从SYN_SENT状态转换到CLOSED状态。
  • 如果SYN+ACK分段丢失:客户端无法区分SYN分段丢失还是SYN+ACK分段丢失,因此它会重新发送SYN分段,并在多次尝试后关闭连接。如果服务器在一定时间内没有收到ACK分段,它会重新发送SYN+ACK分段,并在多次尝试后关闭连接。
  • 如果ACK分段丢失:如果服务器没有收到ACK分段,它会发起重发操作。请注意,客户端不会重新发送ACK分段。如果服务器即使重发了ACK分段仍然无法收到,它会关闭连接。

关闭TCP连接:四次握手

现在让我们转向TCP连接的终止过程。客户端和服务器都可以启动终止。在下图中,客户端启动了终止过程。

步骤1:客户端通过向服务器发送一个FIN分段来启动终止过程,进入FIN_WAIT_1状态。

步骤2:服务器在收到

FIN分段后,回复一个ACK分段,并进入CLOSE_WAIT状态。在收到ACK分段后,客户端进入FIN_WAIT_2状态。

步骤3:服务器完成处理后,向客户端发送一个FIN分段,并进入LAST_ACK状态。

步骤4:客户端在收到FIN分段后,发送一个ACK分段,并进入TIME_WAIT状态。服务器在收到ACK分段后,进入CLOSED状态。等待2MSL(最大报文生存时间)的持续时间后,客户端也转换到CLOSED状态。MSL是TCP分段在网络中存在的最长时间,任意地定义为2分钟。

1e386fb3-7fc6-477a-aa50-c314a462a349_1600x1591.png

当我们深入研究TCP握手时,让我们考虑三种边缘情况:

  1. 客户端宕机
  2. 服务器宕机
  3. 网络电缆损坏

如果客户端在建立TCP连接后宕机会发生什么?

假设在客户端和服务器之间建立了TCP连接,然后客户端突然断线。会发生什么?

如果服务器不尝试向客户端发送数据,服务器无法了解客户端的状态。服务器将保持在ESTABLISHED状态。解决这个问题的方法是实现TCP保活。

使用TCP保活,一组计时器与建立的TCP连接关联。当保活计时器超时时,服务器向客户端发送一个保活探测。该探测是一个不携带数据的ACK分段。如果连续发送多个探测分段而没有客户端的响应,服务器将认为TCP连接已经断开。

5d679ed7-acee-4b70-8536-867bf71a50bc_1486x1600.png

现在让我们更深入地探讨TCP保活的四种情况:

  1. 客户端正常工作。服务器发送一个保活探测并收到回复。保活计时器重置,服务器在计时器再次超时时发送下一个探测。
  2. 客户端进程关闭。在客户端上,当操作系统回收进程资源时,它向服务器发送一个FIN分段。
  3. 客户端机器离线并重新启动。如下图所示,当客户端重新上线时,它对先前的连接一无所知。当服务器尝试通过这个失效的连接向客户端发送数据时,客户端会回复一个RST分段,强制服务器关闭连接。
  4. 客户端机器离线并且不恢复。我们已经讨论过这种情况-在几次无应答的探测之后,服务器将认为连接已经断开。

对于服务器在建立TCP连接后宕机的情况,类似的机制也适用,因为TCP是一种双工协议。

请我吃🍗