本文主要是「三次握手与四次挥手」相关的一些问题
三次握手
- 初始,客户端处于
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
为了防止服务器拥有过多上述的半连接状态,在服务器收到第一次握手的数据后,并不会分配资源。而是利用客户端的SYN
值计算一个Cookie
保存在第二次握手的报文中,返回给客户端,等服务器收到第三次握手的数据包后,根据Cookie
值检查报文的合法性。如果合法再分配资源
TIME_WAIT
防止第四次挥手丢包。
如果客户端发送完第四次挥手数据后,直接切换至CLOSE
状态,第四次挥手数据包丢包时,服务器超时重传第三次挥手数据包。此时如果有新的TCP连接重启这个地址信息的话,处于三次握手阶段,客户端发起的是SYN
请求,而服务器所等待的是ACK
应答。此时会导致发送RST
重建连接。
2MSL
在TIME_WAIT
防止丢包时,客户端从TIME_WAIT
切换至CLOSE
需要等待2MSL
MSL 报文的最大生存时间
如果第三次挥手的包丢包,则第三次挥手从发送到重发,经过2MSL
,此时对于客户端来说,已经过去的时间小于等于1MSL
(发送第四次挥手数据包,过程中丢包),而后接收到重发的第三次握手数据包的时间小于等于1MSL
。即,客户端等待2MSL
未收到FIN
(第三次挥手)则能够确认服务器已经收到第四次挥手数据包。
此外,经过2MSL
后,与该次连接相关的所有报文,都会超过生命周期。防止提前关闭客户端时,部分报文还存活,从而影响新的连接。