TCP的三次握手和四次挥手 记录 基本概念 流程 问题 参考

20210301-20210304 工作时间花了 3天半 理解了下这个很基础,但又没机会接触的知识点。效率着实有点低了。流程图在参考里面已经有了,这里就不贴了,都是重复的。

基本概念

  1. 序号
  • 序列号 seq :当前报文段中的第一个字节的数据编号,4字节。
  • 确认号 ack :期望接收到下一个字节的编号,4字节。
  1. 标志位
  • 确认 ACK :当 ACK = 1 时,确认号字段才有效。
  • 同步 SYN :连接建立时用于同步序号。
  • 终止 FIN :用来释放一个连接。当 FIN = 1 时,表示此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
  • 推送 PSH :提示接收端应用程序立即从TCP缓冲区把数据读走。

流程

连接三次握手

  • 第一次握手:客户端发送 SYN ,seq=x
  • 第二次握手:服务端发送 SYN,ACK,seq = y,ack= x+1
  • 第三次握手:客户端发送 ACK ,seq = x+1,ack = y+1

  • 客户端状态: CLOSED 关闭-> SYN-SENT 同步已发送-> ESTAB-LISHED 建立连接
  • 服务端状态: CLOSED 关闭-> LISTEN 收听-> SYN-RCVD 同步已接收-> ESTAB-LISHED 建立连接

断开连接四次挥手

  • 第一次挥手:客户端发送 FIN ,seq = u
  • 第二次挥手:服务端发送 ACK ,seq = v,ack = u+1
  • 服务端继续发送剩余的数据后,最终的序号 w 。
  • 第三次挥手:服务端发送 FIN ,seq =w, ack = u+1
  • 第四次挥手:客户端发送 ACK , seq=u+1,ack =w+1

  • 客户端状态: ESTAB-LISHED 建立连接-> FIN-WAIT-1 终止等待1-> FIN-WAIT-2 终止等待2-> TIME-WAIT 时间等待-> CLOSED 关闭
  • 服务端状态: ESTAB_LISHED 建立连接-> CLOSE-WAIT 关闭等待-> LAST-ACK 最后确认-> CLOSED 关闭

问题


  1. 为什么连接的时候是三次握手,关闭却是四次挥手?
    连接的握手可以同步 SYN 和确认 ACK 一起发;挥手的时候,有可能服务端不能马上关闭连接,比如还有未发完的消息,这时候不能马上FIN,所以先发 ACK 确认收到关闭确认报文,等待服务端处理完成后,再单独发送FIN给客户端,所以有时候需要四次。

  1. 为什么 TIME_WAIT 状态需要经过 2MSL (最大报文段生存时间)才能返回到 CLOSE 状态?
    客户端发送最后一次 ACK 后,无法确认是否发送成功,假如发送失败,服务端没收到客户端的最后确认 ACK ,则会重发 FIN 。所以如果客户端在 2MSL 内,没收到服务端的FIN,则表明服务端已经关闭连接。

  1. 为什么不能用两次握手进行连接?
    握手是为了确认各自的收发功能是否正常。第一次握手,服务端确认自己的接收功能正常;第二次握手,客户端确认自己的发送功能和接收功能正常;第三次握手,服务端确认自己的发送功能正常。

  1. 如果已经建立了连接,但是客户端突然出现故障怎么办?
    TCP 设有一个保活计时器。服务端每收到一次客户端的请求都会重置这个计时器。若计时器时间内没有收到客户端的请求,则发送探测报文,连续n个探测报文仍然没收到响应,则认为客户端除了故障,接着就关闭连接。

参考

TCP三次握手中SYN,ACK,seq ack的含义
TCPIP的三次握手与四次挥手
Wireshark使用入门