TCP/IP详解--三次握手、四次挥手和TIME_WAIT状态

首先看一个三次握手建立连接的过程

第一次握手:主动打开方发送SYN同步报文段,表示我要和你连接了,自己进入SYN_SENT状态

第二次握手:被动打开方收到SYN报文,恢复ACK报文,自己也发送SYN报文表示我也要连接,进入SYN_RECV状态。

第三次握手:主动打开方收到对方ACK和SYN,自己再发送对SYN的确认。自己就可以进入ESTABLISHED状态表示自己可以通信了。被动打开方收到最后一个ACK,就表示自己的请求对方也收到了,自己进入到ESTABLISHED状态。此时两端都可以通信了。

??为什么是三次握手,两次可以不??

如果是两次握手就可以建立连接,即最后一次主动打开方没有发送确认的ACK,那么当主动打开方发送了SYN后,就异常断开了,而接收方收到发送方的SYN后并不知道对方已挂掉了,他就会以为自己维护了一个完整的连接,一旦之后发送数据就会出现错误。所以不能通过两次握手来建立一个连接。

 

再来看一个正常断开连接的四次挥手图

 

第一次挥手:主动断开方发送结束报文段(FIN),进入FIN_WAIT_1状态

第二次挥手:被动断开方发送对结束报文段的确认(ACK),进入CLOST_WAIT状态(因为此时它可能还有数据需要发送,如果没有数据发送,也可以直接发送ACK和FIN,表示收到对方的FIN请求,并且自己也FIN,这样就会是三次挥手),而此时主动断开方会进入FIN_WAIT_2状态。

第三次挥手:被动断开方发送FIN请求,表示自己数据处理结束了,可以关闭连接了,此时进入LAST_ACK状态,表示等待最后一个ACK到达就可以完全关闭,到达CLOSED状态了。

第四次挥手:主动断开方发送最后一个ACK,表示对对方发送的FIN的确认。然后自己进入TIME_WAIT状态。(是2倍的MSL时间)

以上就是整个四次挥手过程,下面我就TIME_WAIT状态存在的意义和过多时的影响加以说明。

 

TIME_WAIT状态存在主要是为了解决两个问题

  1. 可靠的终止TCP连接。如果最后一个ACK在传输中丢失了,则服务器(被动断开方一般是服务器)会重发最后一个FIN,而如果没有TIME_WAIT状态,而是直接进入CLOSED状态,则客户端收到FIN后会响应一个RST报文,服务器收到后会认为是一个错误。这就是为什么关闭后会维持TIME_WAIT状态,因为它要等待以便重发最后一个ACK。(要想可靠的断开连接,FIN | ACK | FIN | ACK 四个一个都不能少,因为连接是全双工的)
  2. 保证迟到的报文段有足够的时间被识别并处理。这个也很好理解,有些报文段可能还在网络中没有被接收,而如果没有TIME_WAIT状态,直接进入CLOSED,可能会有新的连接用到此端口号建立了新连接,而这些网络中停留的报文段可能被这个新连接接收。而有了TIME_WAIT状态,它的时间是2倍的MSL,经过这么长时间后所有残存的报文段都会丢失(2MSL是因为消息是双向传递的)。这样就保证新的连接不会收到先前网络中残余的数据报了。

 

过多的TIME_WAIT状态带来的影响

  1. 处于TIME_WAIT状态的端口号是不能被重用的,而在高并发的短连接情况下,服务器会在短时间占用大量端口号,而端口号只有0-65535个,再除去系统和其他服务要用的,能用的就更少了,所以大量处于TIME_WAIT会导致客户端连接不上。
  2. 有时候短连接时,“业务处理+传输数据”的时间远远小于2MSL,所以会导致服务器资源严重浪费。

综合以上两方面,持续到达一定量的高并发短连接,会使端口号不足而拒绝客户服务。同时,这些端口号都是服务器临时分配,无法用SO_REUSEADDR选项来解决这个问题。(当设置SO_REUSEADDR选项后,即使处于TIME_WAIT状态下的端口也可以使用)

 

普遍情况下解决TIME_WAIT状态的方法

  1. 通过设置socket选项SO_REUSEADDR选项来强制使用处于TIME_WAIT下的端口。(SO_REUSEADDR选项就是重用本地地址的)
  2. 修改内核参数 /proc/sys/net/ipv4/tcp_tw_recycle来快速回收关闭的socket。

修改方法:

net.ipv4.tcp_tw_reuse = 1     重用

net.ipv4.tcp_tw_recycle = 1    快速回收

 

此外修改syncookies这个功能,如下:

net.ipv4.tcp_syncookies = 1

打开这个syncookies的目的实际上是:“在服务器资源(并非单指端口资源,拒绝服务有很多种资源不足的情况)不足的情况下,尽量不要拒绝TCP的syn(连接)请求,尽量把syn请求缓存起来,留着过会儿有能力的时候处理这些TCP的连接请求”。

 

猜你喜欢

转载自blog.csdn.net/ShWe_yayaya/article/details/81540950
今日推荐