skip to content
天真笔录

TCP三次握手与四次挥手

/ 5 min read

tcp

三次握手

  1. 第一次:客户端发送SYN标识位,seq序列号到服务器端,客户端状态:SYN_SEND
  2. 第二次:服务器端发送SYN标识位,ACK标识位,ack确认号,seq序列号, 服务器端状态:SYN_RCVD
    1. Ack=J+1(J为第一次seq的值)
  3. 客户端发送ACK标识位,ack确认号,客户端状态:ESTABLISHED
    1. Ack=K+1(K为第二次seq的值)
  4. 服务器端收到ACK,进入ESTABLISHED,不算握手

    Ack=Seq+1

字段认识

  • seq: 序号(解决网络包乱序)
  • ack:确认号(解决网络包丢失)
  • 标识位6个
    • ACK:确认号(Acknowledgement)
    • SYN:请求同步(Synchronization)
    • URG:紧急指针
    • PUSH:接收方应尽快将这个报文交给应用层
    • RST:重置连接
    • FIN:释放一个连接

      1表示开启,0表示关闭

使用wireshark来分析三次握手的过程

第一次握手分析

tcp1
  • 619: 50595 -> 3000
  1. [SYN]
  2. Seq = 0
  3. MSS=1460,表示最大报文长度

第二次握手分析

tcp2
  • 620: 3000 -> 50595
  1. [SYN, ACK]
  2. Seq=0
  3. Ack=1

第三次握手分析

tcp3
  • 621: 50595 -> 3000
  1. [ACK]
  2. Seq=1
  3. Ack=1

为什么握手是三次?

因为要保持连接和可靠性约束,TCP 协议要保证每一条发出的数据必须给出ACK(也就是响应)。

  • 第一次:客户端发送SYN表示请求建立连接(服务端知道了客户端有发送能力)
  • 第二次:服务器端发送SYN ACK之后,表示服务器端已经准备好了(客户端知道服务端具有接收发送能力)
  • 第三次:服务器端此时还不知道客户端是否也准备好,所以需要第三次握手

四次挥手

断开连接时要发送四次数据,故称四次挥手

  1. 第一次挥手:挥手前服务器与客户端都处于ESTABLISHED状态。客户端发送一个FIN报文,用来关闭客户端到服务器的数据传输,此时客户端处于FIN_WAIT_1状态
  2. 第二次挥手:当服务端收到FIN之后,会发送ACK报文,并且把客户端的序列号值加1作为ACK报文的序列号值,表明已经收到客户端的报文了,此时服务端处于CLOSE_WAIT状态。
  3. 第三次挥手:如果服务端同意关闭连接,则会向客户端发送一个FIN报文,并且指定一个序列号,此时服务端处于LAST_ACK状态
  4. 第四次挥手:当客户端收到ACK之后,处于FIN_WAIT_2状态。待收到FIN报文时发送一个ACK报文作为应对,并且把服务端的序列号值+1作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态。等待一段时间后会进入CLOSED状态,当服务端收到ACK报文之后,也会变为CLOSED状态,此时连接正式关闭

为什么挥手需要四次

  1. 当服务端收到客户端FIN报文后,发送的ACK报文只是用来应答的,并不表示服务端也希望立即关闭连接
  2. 当只有服务端把所有的报文都发送完了,才会发送FIN报文,告诉客户端可以断开连接了,因此在断开连接时需要四次挥手