1.TCP三次握手的过程理解。
![](https://i-blog.csdnimg.cn/blog_migrate/52aeb223eead87ccbb21edd4af104bfe.png)
第一次握手:客户端发送连接请求,发送一个SYN标记的包(SYN = 1),并且进入到SYN-SENT状态,等待服务器端响应;
第二次握手 : 服务器收到客户端发来的连接请求后,先检验一下ack=x+1,如果是的话,服务器响应一个SYN包返回去,此时服务器端进入SYN-RCVD状态;
第三次握手:客户端接收到服务器的响应,检验ack = y + 1,成功则发送一个ACK包,发送完毕后,进入ESTABLISHED状态,完成三次握手,建立会话。
疑问:
为什么两次握手不可以?
上面已经了解了TCP的三次握手的过程,现在我们假设一下,我们只要两次握手,会发生什么。
首先客户端发送请求,然后服务器接受请求后再发送给客户端表示接收到了,并进入ESTABLISHED状态,此时如果我们服务器端发送的请求丢失了,那么客户端就会一直等着服务器的这个确认,但是此时服务器已经开启了会话,他不会再发送确认包,此时两端就卡死了,并且两端也都消耗着资源,互相等待。
所以,TCP需要三次握手才能保证他的可靠连接。
要是第三次的ACK确认包在网络中丢失了怎么办?
服务端:要是ACK包丢失了,那么服务装的状态就会一直在SYN-RCVD状态,根据TCP的超时重传,它会等待3秒、6秒、12秒后重新发送SYN+ACK包,要是在重传了一定次数后还没响应,就会关掉这个连接。
客户端:此时客户端已经进入了ESTABLISHED状态,当客户端给服务端发送数据的时候,服务端此时会响应 RST包,那么客户端就会明白服务端出错了。
2.TCP的四次挥手过程理解。
![](https://i-blog.csdnimg.cn/blog_migrate/0afe6946afb8c8acaa2d5735d4437f96.png)
第一次挥手:客户端发送FIN,进入FIN-WAIT状态,关掉客户端到服务端的数据传送,表示不会在给服务端发送新的数据了,虽然不发送了新的数据,但是还是可以接收。
第二次挥手: 服务器收到FIN包后,同样要检验ack的值后再发送一个ACK包给对方,进入到CLOSE-WAIT状态。
第三次挥手: 服务器给客户端发送FIN包,表示自己不会再给客户端发送新数据了,进入到LAST-ACK状态。
第四次挥手: 客户端收到FIN包后,检验完ACK后再发送一个ACK包回去,进入到TIME-WAIT状态,此时连接还没有完全关闭,要经过2∗∗MSL(最长报文段寿命)的时间后,才进入到CLOSE状态。到这里,四次挥手就完成了。
疑问
为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入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连接。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
总结
在我看来,不管是三次握手,还是四次挥手也好,都是TCP为了保证可靠传输的手段,我们从这个角度去理解就好理解一些。
三次握手,就是确保我们传数据的双方都已经准备好。
四次挥手,就是确保我之前没发送完的数据一定要发送完,本着这个去理解,就可以更好的理解了。