TCP的三次挥手和四次握手
TCP之所以要用三次握手,主要为了完成如下几个目标
1)防止旧的SYN生效,比如 原来发出的SYN ,由于网络环境比较差,一直没有发送到服务端,客户端又发出了新的SYN,
这时候,如果旧的SYN ACK已经返回,那么,client就要回复一个RST给到服务器端,因为新SYN已经发出了,如果没有
三次握手,那么就可能造成多次连接的存在
2)同步双方的序列号
四次挥手:
四次挥手的过程:
首先 主动断开的一方,发送FIN 报文,进入FIN_WAIT1 状态,被动的一方收到以后,发送 ACK报文,进入CLOSED_WAITED状态,
主动断开的一方收到ACK报文以后,进入FIN_WAIT2状态。CLOSED_WAIT的作用是代表被断开端继续发送没有发送完成的数据。处理
完成以后,继续发送FIN包,主动方收到以后发送ACK,进入TIME_WAIT状态,而被动方进入LAST_ACK状态,在收到最后一个ACK以后,被动方
关闭,但是主动方的TIME_WAIT会继续一段时间。
TIME_WAI的时长是2MSL,也就是报文的最大生存时间的2倍,也就是60s。
为什么需要TIME_WAIT状态:
1)防止收到旧的报文
假如 被动方发送的一个SEQ = 301的报文,但是这个报文因为网络原因延迟,这个时候,如果发生了断开连接又重连的情况,新连接就有可能收到这个旧的数据包。
2)保证连接正常关闭
如果最后一个ACK失效,那么,被动方就会发新的FIN报文,这样一来一回正好2MSL,如果没有这个等待或者过短,那么如果ACK丢了,就会出现被动方无法关闭的情况
大量CLOSE_TIME产生的原因:
大量的close wait 产生的原因是因为客户端异常断开造成的,CLOSE_WAIT大量存在会占用过多的fd导致新的连接没法连接,
解决办法,如果客户端异常断开,需要在epoll里面监听 EPOLLRDHUP这个事件,在收到事件以后,就colse掉这个fd。