TCP协议是互联网的基础之一,它提供了可靠的数据传输服务。TCP连接的建立和断开过程——三次握手和四次挥手——是网络面试题里的高频考点,但真正理解其背后原因的人并不多。
先说三次握手。客户端先发一个SYN包,带上初始序列号seq=x,进入SYN_SENT状态。服务端收到后,回复一个SYN+ACK包,确认号ack=x+1,同时带上自己的初始序列号seq=y,进入SYN_RCVD状态。客户端再发一个ACK包,确认号ack=y+1,双方都进入ESTABLISHED状态,连接建立完成。
为什么是三次而不是两次?这是为了确认双方的发送和接收能力都正常。第一次握手确认了客户端的发送能力,第二次确认了服务端的接收和发送能力,第三次确认了客户端的接收能力。两次握手的话,服务端无法确认客户端的接收是否正常。
四次挥手的过程是这样的:主动关闭方先发一个FIN包,进入FIN_WAIT_1状态;被动方收到后,回复一个ACK,进入CLOSE_WAIT状态;等被动方也准备好关闭时,再发一个FIN包;主动方收到后回复ACK,进入TIME_WAIT状态,等2MSL时间后关闭。
为什么挥手要四次?因为TCP连接是全双工的,双方关闭连接要分开进行。主动方发FIN只表示"我没有数据要发了",但被动方可能还有数据没发完。所以被动方先回一个ACK表示知道了,等自己也发完数据后再发FIN。这就是挥手需要四次的原因。
TIME_WAIT状态是个有意思的设计。主动方发送最后一个ACK后,不立即关闭连接,而是等待2MSL时间。这是为了确保最后一个ACK能被对方收到。如果被动方没收到,会重发FIN,主动方在TIME_WAIT期间还能重新发送ACK。2MSL是报文最大生存时间的两倍,足够让一个报文在网络中走一个来回。
这些机制看似繁琐,实则都是为了保证TCP连接的可靠性。在实际网络编程中,理解这些底层逻辑有助于排查连接问题、优化连接管理。比如大量TIME_WAIT连接说明可能存在频繁创建和关闭连接的情况,可以考虑使用连接复用来改善。
下一篇:没有了