为什么关闭连接的需要四次挥手,而建立连接却只要三次握手呢?
TCP连接是全双工的,这意味者数据可以在俩个方向上同时传输,(所以关闭连接时需要分别处理俩个方向的数据传输)当一方想要关闭连接时,它可能仍然希望接收来自另一方的数据。因此每个方向都需要单独的FIN和ACK来关闭
- 第一步:主动关闭方(如客户端)发送 FIN,表明 "我不再发送数据,但仍可接收数据"。
- 第二步:被动关闭方(如服务器)收到 FIN 后,立即回复 ACK,确认 "已收到关闭请求",但此时服务器可能仍有数据未传输完毕,因此不会立即发送 FIN。
- 第三步:当服务器数据传输完毕后,主动发送 FIN,表明 "我也不再发送数据"。
- 第四步 :客户端收到服务器的 FIN 后,回复 ACK 确认,双方最终关闭连接。
结论 :ACK 与 FIN 分离(需四次交互),是因为被动关闭方可能需要时间处理剩余数据,无法在收到 FIN 时立即关闭发送通道。
四次挥手确保所有未确认的数据都已经被接收,并且双方都直到双方已经准备好关闭连接
三次握手主要目的是同步双方的初始序列号,并且确认双方都有能力发送和接收数据。可以避免重复连接
对比三次握手
握手时服务器可以在一个报文ACK+SYN中同时完成确认客户端请求和发起自身请求,因为此时服务器尚未开始发送数据
而挥手时,服务器可能需要继续处理和发送剩余数据(先处理完已接收的数据),再发起关闭。所以ACK和FIN必须分开
可以变成三次挥手:当服务器收到FIN后,立即确认且无数据待发送,可以将ACK和FIN合并
为什么连接建立的时候是三次握手,可以改成两次握手吗?
- 至少一次请求(SYN)确认客户端发送能力;
- 至少一次响应(SYN+ACK)确认服务器接收和发送能力;
- 至少一次最终确认(ACK)确认客户端接收能力。
通过第三步客户端发送ACK,服务器能确认客户端不仅能发送数据还可以接收数据
若服务器返回的ACK+SYN因网络故障丢失,客户端会认为连接未建立,而服务器认为连接建立。此时服务器会持续等待客户端的数据,造成资源浪费(端口占用)
第三步客户端发送ACK的作用:服务器接收ACK可以确认客户端能正常接收服务器发送的ACK+SYN。即客户端收发能力正常。至此客户端服务器收发能力全部通过,确保双向通信可靠
理论上俩次握手可以确保网络绝对可靠。客户端和服务器均能唯一标识历史连接
为什么主动断开方在TIME-WAIT状态必须等待2MSL的时间
主动断开连接的一方在最后一次挥手发送ACK后,会进入time---wait状态并等待2倍msl时间报文最大生存时间。
-
确保旧连接的所有报文在网络中完全消失避免新连接
-
确保最后一次ACK可靠到达
若ACK在传输中丢失,服务器会重传第三次挥手的FIN报文,确保服务器可以正常关闭
- 保证双向连接完全终止。tcp是全双工协议,连接的关闭需确保俩个方向的数据流均终止
如果已经建立了连接,但是Client端突然出现故障了怎么办?
若客户端故障前正在向服务器发送数据,服务器收到部分数据后,客户端突然中断。
服务器无法直接感知客户端状态变化,需要通过TCP协议的保活机制和超时重传机制来检测并处理异常
超时重传:若重传失败客户端无响应服务器认为该方向的数据流已经中断,但另一方服务器-客户端还可以开放