TCP中的三次握手和四次挥手
参考链接
SYN:请求建立链路 ACK:应答 FIN:终止当前链路 DATA:传输数据
在socket编程中,三次握手由connect触发,四次挥手由close触发。
三次握手
客户端和服务器之间没有建立连接,并且两者之间试图建立链接。
第一次握手:此时客户端TCP进程处于“CLOSE关闭状态”。当客户端试图发起TCP连接时,客户端状态从“CLOSE”进入到“SYN-SEND”状态,并且向处于“LISTEN监听状态”的服务器端TCP进程发送第一个“SYN数据包”,注意,此时的SYN控制位是1。
第二次握手:服务器端接受到客户端发来的SYN数据包。如果同意建立连接,那么服务器端会向客户端发送“SYN+ACK”报文。此时SYN=1,ACK=1.。同时服务器从LISTEN状态进入SYN-RCVD状态。
第三次握手:客户端接收到服务器端发来的SYN/ACK包。此时,客户端发送ACK包给服务器端,并且客户端从SYN-SEND状态进入ESTABLISHED(已建立链接)状态。(当服务器端接受到客户端发来的ACK包时,状态也变成ESTABLISHED)
四次挥手 参考连接
客户端和服务器端之间已经建立了连接,并且两者试图断开连接。客户端和服务器端都可以主动提出释放连接的请求,顶部的图和下面的解释都时客户端主动提出释放连接。
第一次挥手:客户端此时的状态时ESTABLISHED,发送第一个FIN报文给服务器端,标志位FIN=1。同时客户端的状态变成INF-WAIT-1,表示释放等待1。
第二次挥手:服务器端接受到来自客户端的FIN数据包。这个时候,客户端是已经没有数据要发送了,但是服务器端仍然有可能有数据要发送给客户端,所以,当服务器端接受到FIN包后,会发送一个ACK给客户端,表示“我收到了你的请求,但是我还没准备好,请继续等我的消息”。客户端在接收了服务器端的ACK后,状态由FIN-WAIT-1转到FIN-WAIT-2,并且继续等待服务器端的消息;服务器端转为LAST-WAIT状态。(这个时候,服务器端是可以继续发送数据给客户端的)
第三次挥手:服务器端没有了数据要发送给客户端,于是便发送FIN给客户端,告诉客户端可以关闭了。同时,服务器端的状态从CLOSE-WAIT转为LAST-ACK。
第四次挥手:客户端接受到服务器端的FIN,发送ACK给服务器端,表示最后一次确认关闭,自身进入TIME-WAIT状态,如果在2MSL(最长报文寿命)时间内没有来自服务器端的数据,就进入CLOSE状态,关闭连接。服务器端在接受到了ACK后,从LAST-WAIT进入CLOSE状态,关闭连接。
思考:
四次挥手中,最后一次挥手为什么等待2MSL?发送ACK的含义是什么?
关于四次挥手中,第四次挥手的理解:
在第四次挥手中,客户端发送了最后一个ACK给服务器进行再次确认,同时服务器端也在TIME-WAIT状态 中等待客户端的最后一个ACK,当服务器收到了ACK后,确认与客户端之间的关闭是正确的,进入CLOSE状态;如果,服务器端在TIME-WAIT状态中没有接收到ACK,或者说客户端发送给服务器端的ACK包中途丢失(劫持),那么服务器端就会再次发送FIN的包给客户端,直到接受到ACK包为止。
当客户端发送了ACK包并且成功到达了服务器端,那么服务器端会进入CLOSE状态(不发送任何数据包给客户端),客户端等待2MSL后,没有接收到任何数据,便能确认服务器端接受到了ACK包,客户端进入CLOSE状态。
2MSL:MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。RFC 793中规定MSL为2分钟,实际应用中通常设置为30秒、1分钟、2分钟等。客户端在第四次挥手中,发送了ACK给服务器端,数据包到达服务器端要一个MSL的时间,同时,服务器端返回FIN包给客户端也要一个MSL的时间(如果服务器端没有接收到ACK包的话),所以客户端等待2MSL,超过2MSL后就进入关闭状态(没有收到来自服务器端的FIN)。
暂时未弄懂的地方:如果TIME-WAITE中,ACK包一直丢失。。。。。就会一直发送FIN。。。。。。然后怎么解决。。。。。