TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在TCP连接的建立和维护中,有一种被称为TCP状态机的机制,它描述了TCP连接在其生命周期内可能经历的所有状态。

TCP状态机中的主要状态包括:

  1. CLOSED:表示没有任何连接。这是初始状态,也是关闭连接后的状态。
  2. LISTEN:服务器在等待来自客户端的连接请求。
  3. SYN_SENT:在发送连接请求后等待匹配的连接请求。这是客户端在发送连接请求后的状态。
  4. SYN_RECEIVED:在接收和发送一个连接请求后等待对连接请求的确认。这是服务器在收到SYN后,回复SYN-ACK后的状态。
  5. ESTABLISHED:一个已经建立的连接,数据可以在两个方向上发送。
  6. FIN_WAIT_1:等待连接终止的请求,或者确认已经发送的连接终止请求。
  7. FIN_WAIT_2:等待对方的连接终止请求。
  8. CLOSE_WAIT:等待从本地用户发来的连接终止请求。
  9. CLOSING:等待对方对连接终止的确认。
  10. LAST_ACK:等待最后一个对已经终止的连接的确认。
  11. TIME_WAIT:等待足够的时间以确保对方接收到连接终止的确认。

TCP连接的建立和关闭过程中,会使用到一些特殊的标志位,主要有:

  • SYN:同步序列编号(Synchronize Sequence Numbers)。用来在连接建立时同步序列号。SYN=1,ACK=0表示这是一个连接请求。
  • ACK:确认字段(Acknowledge)。只有当ACK=1时,确认号字段才有效。ACK=0表示确认号无效。
  • FIN:结束位(Finish)。用来释放一个连接。FIN=1表示此次数据传送完毕,没有数据可以发送了。
  • RST:复位标志(Reset)。用来重置对方的连接。
  • PSH:推送标志(Push Function)。接收方应该尽快将这个报文段交给应用层而不用等到整个缓冲区都满了再交给应用层。
  • URG:紧急指针(Urgent Pointer)。仅当URG=1时才有意义。它告诉系统此报文段中有紧急数据,应尽快传送(相对于其他部分的数据)。

以上就是TCP状态机的主要状态和使用到的主要标志位。


TCP协议的连接建立过程和连接结束过程非常重要,下面详细介绍一下这两个过程:

1. TCP连接的建立——三次握手

TCP连接的建立通常被称为“三次握手”(Three-way Handshake):

  • 步骤一:客户端发送一个TCP报文段给服务器。报文段中SYN标志位为1,初始序列号为x;其他部分(如应用数据)为空。这个过程,我们把状态称为SYN_SENT。
  • 步骤二:服务器收到SYN报文段后,应当确认客户的SYN(ACK=x+1),同时自己也发送一个SYN报文段(SYN=y),即SYN+ACK报文段。此时,服务器进入SYN_RECEIVED状态。
  • 步骤三:客户端收到服务器的SYN+ACK报文段后,应当再次发送确认(ACK=y+1)。此包发送完毕后,客户端和服务器都进入ESTABLISHED状态,完成三次握手。

这个过程的主要目的是同步双方的初始序列号。 tcp1

2. TCP连接的结束——四次挥手

TCP连接的结束通常被称为“四次挥手”(Four-way Handshake):

  • 步骤一:当主动方(可以是客户端,也可以是服务器)完成数据发送任务后,可以发送一个FIN报文段来关闭连接,此时,主动方进入FIN_WAIT_1状态。
  • 步骤二:被动方收到FIN报文段后,发送一个ACK报文段,确认序号为收到序号+1(ACK=FIN+1)。此时,被动方进入CLOSE_WAIT状态,主动方接到ACK后,进入FIN_WAIT_2状态。
  • 步骤三:被动方在等待一段时间(关闭延迟)后,确认数据发送完成,并发送一个FIN报文段给主动方,进入LAST_ACK状态。
  • 步骤四:主动方收到FIN后,发送一个ACK给被动方,进入TIME_WAIT状态,等待足够的时间以确保应答被接收(通常设置为2MSL,即两倍的最大报文段生存时间)。被动方收到ACK后,进入CLOSED状态。主动方等待2MSL后也转到CLOSED状态。

以上就是TCP协议的连接建立和连接结束过程。

在正常的 TCP 通信中,每个方向的数据传输是独立的,因此主动方和被动方的序列号是分开的。每个方向的序列号是独立递增的,表示该方向上已经发送的数据字节总数。因此,在图中看到不同的序列号 u, v, w 是正常的,这表示在两个方向上各自的数据流。

tcp2

没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手。 tcp3