目录
1.TCP四次挥手过程
2.挥手连环发问
理论篇:
(一)深入浅出TCPIP之理解TCP报文格式和交互流程
(二)深入浅出TCPIP之再识TCP,理解TCP三次握手(上)
(三)深入浅出TCPIP之再识TCP,理解TCP四次挥手(上)
(四)深入浅出TCPIP之TCP三次握手和四次挥手(下)的抓包分析
(五)深入浅出TCPIP之TCP流量控制
(六)深入浅出TCPIP之TCP拥塞控制
(七)深入浅出TCPIP之深入浅出TCPIP之TCP重传机制
(八)深入浅出TCPIP之TCP长连接与短连接详解
(九)深入浅出TCPIP之网络同步异步
(十)深入浅出TCPIP之网络阻塞和非阻塞
(十一)深入浅出TCPIP之TCP粘包问题
(十二)深入浅出TCPIP之Nagle算法
(十三) 深入浅出TCPIP之TCP套接字参数
(十四)深入浅出TCPIP之初识UDP理解报文格式和交互流程
(十五)非常全面的TCPIP面试宝典-进入大厂必备总结
(十六)深入浅出TCPIP之Hello CDN
....
(二十)深入浅出TCPIP之epoll的一些思考
实践篇:
深入浅出TCPIP之实战篇—用c++开发一个http服务器(二十一)
其他实践篇+游戏开发中的网络问题疑难杂症解读 正在完善。。。
上篇文章对于"三次握手”做了说明。本节我们对不常听见的“四次挥手”为大家详尽, 直观,完整地绍“挥手”的过程。
所谓的四次挥手即tcp连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。以下为客户端主动发起释放连接的图解:
TCP连接的释放一共需要四步,因此称为『四次挥手』。
我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。
第一次挥手
若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:
FIN=1,seq=u。此时,A将进入FIN-WAIT-1状态。
第二次挥手
B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:
ACK=1,seq=v,ack=u+1。
A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求。
第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。
第三次挥手
当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。B便进入LAST-ACK状态。
第四次挥手
A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。
这里借鉴一张网络图片可形象描述四次挥手的过程:
1.为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
2.为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
3.状态为TIME_WAIT是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?
主动关闭的一方在发送最后一个 ack 后就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。
也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。