TCP三次握手四次挥手

一、基础理论

1、TCP的标志位

标志位 含义
SYN(synchronous) 在建立连接时使用,表示请求同步序列号。当SYN=1时,该数据段用于发起一个连接。
ACK(acknowledgement) 用于确认接收到的数据段,如果ACK=1,确认应答的字段变为有效
FIN(finish) 在关闭连接时使用,当FIN=1时,表示发送端已完成数据发送任务,希望断开连接。
RST(reset) 用于复位异常或无效的连接,或者拒绝非法的数据段,当RST=1时,表示 TCP 连接中出现异常必须强制断开连接。
PSH(push) 指示接收端应该尽快将数据交付给上层应用程序,而不是等到缓冲区满后再交付。
URG (Urgent Pointer) 当URG=1时,报文中有紧急数据需要立即处理,此时包含紧急指针字段来指示紧急数据的末尾位置。

2、TCP的状态码

状态码 含义
CLOSED 没有任何连接状态
LISTEN 服务器端处于监听状态,等待客户端发起连接请求。
SYN_SENT 在发送连接请求后等待确认
SYN_RCVD 服务器收到客户端的SYN,并发回一个SYN+ACK作为响应,等待客户端确认。
ESTABLISHED 连接建立,可以进行正常的数据传输
FIN_WAIT_1 已经发送关闭请求,等待确认(主动关闭)
CLOSE_WAIT 对方发送FIN后,本地端收到并确认后进入此状态,表示本端应用程序尚未关闭连接。
FIN_WAIT_2 收到了对方对FIN的确认后进入的状态,继续等待对方也关闭连接。
LAST_ACK 已经发送了FIN,正在等待最后一个ACK以彻底关闭连接。
TIME_WAIT 发送了FIN并收到ACK之后,等待足够时间确保远程主机收到最后的ACK,避免旧分组在网络中滞留导致的问题。
CLOSING 同时收到了FIN且正要发送FIN时,两边都在关闭连接,但还没有收到对方对FIN的确认。
CLOSED(再次) 收到并确认了对方的FIN后,最终关闭连接,回到初始状态。

二、TCP连接的建立与释放

1、三次握手

  • 第一次握手:

    • 一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
    • 客户端发送连接请求报文段,将 SYN 标志位设置为 1,表示请求建立连接。seqx。然后,客户端进入 SYN_SENT 状态,等待服务器的确认;
    • 标志位为SYN,表示""请求建立新连接";
      序号为seq=x(x一般为1);
  • 第二次握手:

    • 服务器收到客户端发送的 SYN 报文段,需要对这个 SYN 报文段进行确认,设置 ackx+1(seq+1);同时,自己自己还要发送 SYN 请求信息,将 SYN 标志位置为 1,seqy;服务器端将上述所有信息放到一个报文段(即 SYN+ACK 报文段)中,一并发送给客户端,此时服务器进入 SYN_RCVD 状态;
    • 标志位为SYN和ACK,表示"确认客户端的报文seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接"(即告诉客户端,服务器收到了你的数据);
      序号为seq=y;
      确认号为ack=x+1,表示收到客户端的序号seq并将其值加1作为自己确认号ack的值;
  • 第三次握手:

    • 客户端收到服务器的 SYN+ACK 报文段。然后将ACK标志位设置为 1,表示确认收到服务器同意连接的信号,向服务器发送 ACK 报文段,这个报文段发送完毕以后,客户端和服务器端都进入 ESTABLISHED 状态,完成 TCP 三次握手。
    • 标志位为ACK,表示"确认收到服务器端同意连接的信号"(即告诉服务器,我知道你收到我发的数据了);
      序号为seq=x+1,表示收到服务器端的确认号ack,并将其值作为自己的序号值;
      确认号为ack=y+1,表示收到服务器端序号seq,并将其值加1作为自己的确认号ack的值;

2、四次挥手

  • 第一次挥手:

    • 客户端想要释放连接,向服务器发送FIN报文,将FIN标记位设置为1,同时指定一个序列号seq=u。随后客户端进入FIN_WAIT_1状态。

    • 标志位为FIN,表示"请求释放连接";

      序号为seq=u;

  • 第二次挥手:

    • 服务器端接收到从客户端发出的FIN报文后,确认了客户端想要释放连接,随后服务器端

      会发送ACK报文,并且把客户端的序列号+1作为ACK报文的序列号值。表明已经收到客户端的报文,此时服务器端处于CLOSE_WAIT状态。

    • 随后服务器端开始准备释放服务器端到客户端方向上的连接。客户端收到从服务器端发出的ACK应答报文,确认了服务器收到了客户端发出的释放连接请求。随后客户端结束FIN_WAIT_1状态进入FIN_WAIT_2状态。

    • 标志位为ACK,表示"接收到客户端发送的释放连接请求";

      序号为seq=v;

      确认号为ack=u+1;表示是在接收到客户端报文的基础上,将其序号seq值加1作为本段报文确认号ack的值

  • 第三次挥手:

    • 服务器端自从发出ACK确认报文之后,经过CLOSE_WAIT阶段,服务器端将最后数据发送完毕后就向客户端发出连接释放报文段,报文包含FINACK标志位。随后服务器端结束CLOSE_WAIT状态,进入LAST_ACK状态。并且停止再服务器端到客户端方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。

    • 标记位为FIN和ACK,表示"已经准备好释放连接了"。

      序号为seq=w;

      确认号为ack=u+1;

  • 第四次挥手:

    • 客户端收到来自服务器端发出的FIN+ACK报文,确认了服务器端已做好释放连接的准备,结束FIN_WAIT_2状态,并向服务器端发送一个ACK报文作为应答,将服务器端的序列号值+1作为自己的ACK报文的序列号值。进入TIME_WAIT状态。

    • 服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。

    • 客户端等待计时器设置的时间2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,至此完成"四次挥手"。

    • 标记位为ACK,表示"接收到服务器准备好释放连接的信号"。

      序号为seq=u+1;表示是在收到了服务器端报文的基础上,将其确认号ack值作为本段报文序号的值。

      确认号为ack=w+1;表示是在收到了服务器端报文的基础上,将其序号seq值作为本段报文确认号的值。

三、更多面试题参考

4.1 TCP 三次握手与四次挥手面试题 | 小林coding (xiaolincoding.com)

面试官,不要再问我三次握手和四次挥手 | 猿人谷 (yuanrengu.com)

热门相关:禁止的爱:禁忌   上海假期粤语   冲上九重天国语   跌打婆与辣妹粤语   铁血大明