残局

不过在等杀死希望的最后一刀

0%

TCP连接的建立与断开

本文主要是「三次握手与四次挥手」相关的一些问题

三次握手

  • 初始,客户端处于close状态,服务器处于listen状态
  • 第一次握手 — 客户端向服务器端发送一个SYN位,切换状态至SYN_SENT
  • 第二次握手 — 服务器收到SYN报文,向客户端回一个确认报文ACK,切换状态至SYN_REVD;同时,发送自己的SYN报文进行应答。
  • 第三次握手 — 客户端收到SYN报文后,发送ACK报文给服务器。同时,自身状态切换至established
  • 服务器端收到ACK报文后,切换自身状态为established

四次挥手

  • 客户端、服务器都处于established状态,进行数据传输。
  • 第一次挥手 — 客户端发送一个FIN位,表示不再发送请求。同时,状态切换至FIN_WAIT_1
  • 第二次挥手 — 服务器收到客户端的结束请求,发送一个ACK位,表示已收到客户端报文。同时,服务器切换状态为CLOSE_WAIT
  • 客户端收到第二次挥手的报文后,切换自身状态为FIN_WAIT_2
  • 第三次挥手 — 服务器传完数据后,向客户端发送结束报文FIN位,进入LAST_ACK状态。
  • 第四次挥手 — 客户端收到报文后,发送ACK进行应答。同时切换自身状态为TIME_WAIT
  • 服务器收到ACK报文后,关闭连接。切换为CLOSE状态
  • 客户端在发送第四次握手后等待2MSL切换为CLOSE状态,关闭连接。

相关问题

为什么握手三次

确认双方都能发送、接收数据。

  • 第一次握手 — 服务器端知道客户端可以发送数据
  • 第二次握手 — 客户端知道服务器端可以发送数据、可以接受数据。
  • 第三次握手 — 服务器端知道客户端可以接收数据

FYN泛洪

利用三次握手的特性,攻击者疯狂发送第一次握手的数据包,收到服务器第二次握手数据包后,并不会回第三次握手数据包。服务器收不到相应的ACK位一直重发第二次握手的数据包,最终导致服务器资源耗尽。

为了防止服务器拥有过多上述的半连接状态,在服务器收到第一次握手的数据后,并不会分配资源。而是利用客户端的SYN值计算一个Cookie保存在第二次握手的报文中,返回给客户端,等服务器收到第三次握手的数据包后,根据Cookie值检查报文的合法性。如果合法再分配资源

TIME_WAIT

防止第四次挥手丢包。

如果客户端发送完第四次挥手数据后,直接切换至CLOSE状态,第四次挥手数据包丢包时,服务器超时重传第三次挥手数据包。此时如果有新的TCP连接重启这个地址信息的话,处于三次握手阶段,客户端发起的是SYN请求,而服务器所等待的是ACK应答。此时会导致发送RST重建连接。

2MSL

TIME_WAIT防止丢包时,客户端从TIME_WAIT切换至CLOSE需要等待2MSL

MSL 报文的最大生存时间

如果第三次挥手的包丢包,则第三次挥手从发送到重发,经过2MSL,此时对于客户端来说,已经过去的时间小于等于1MSL(发送第四次挥手数据包,过程中丢包),而后接收到重发的第三次握手数据包的时间小于等于1MSL。即,客户端等待2MSL未收到FIN(第三次挥手)则能够确认服务器已经收到第四次挥手数据包。

此外,经过2MSL后,与该次连接相关的所有报文,都会超过生命周期。防止提前关闭客户端时,部分报文还存活,从而影响新的连接。

-------------感谢阅读有缘再见-------------