TCP的三次握手和四次挥手
TCP的三次握手
第一次:客户端向服务端发出了请求连接请求报文, 首部中的同部位SYN=1,同时选择一个厨师序号seq = x。这时,客户端进入SYN-SENT(同步已发送)状态
第二次:服务端收到请求报文后,如果同意建立连接,则向客户端发送确认。在确认报文中SYN和ACK都置1,确认号是 ack = x + 1,自己选择一个初始序号seq = y,服务器进入SYN-RCVD(同步收到)状态
第三次:客户端收到服务端确认后,还要想服务端给出确认。确认报文段的ACK置1,确认号2 ack = y + 1,自己的序号 seq = x + 1。这是TCP的连接已建立,客户端进入ESTABLISHED(已建立连接)状态。
当服务端收到客户端的确认后,也进入ESTABLISHED状态
为什么客户端还要在发送一次确认呢?
这是为了防止已失效的链接请求报文突然又传到了服务端。因而产生错误
“已失效的连接请求报文”是这样产生的:
客户端发出了第一个连接请求,由于网络等原因导致长时间滞留但是没有丢失,以致延误到连接释放以后的某个时间才到达服务端。按理说这应该是一个早就失效的报文段,但是服务端收到这个失效的报文段后,他不知道你是失效的报文噻,所以就会误以为客户端有发来了一个请求,于是就向客户端发出了确认报文同意连接。假设我们没有第三次的握手,那岂不是又建立了一个连接。
但是我客户端并没有发出建立连接的请求啊,所以我就不搭理服务器,不给你发送数据。但是服务器以为新的连接已经建立好了,等着你客户端发来数据他就一直等啊等啊等啊,确怎么也等不到。这样就会导致服务器的许多资源就这么浪费了。
参用了三次握手的办法可以防止上述现象的发生,就如刚才的情况,服务器收不到客户端的确认就知道客户端没有要求建立连接。
TCP的四次挥手
第一次:客户端的应用进程先发出连接释放报文,并停止发送数据,主动关闭TCP连接。终止k控制位FIN置1,序号seq = u,这时客户端进入FIN-WAIT-1(终止等待1)状态,等待服务端的确认。
第二次:客户端收到连接释放报文后发出确认,确认号是ack = u + 1,序号是v,然后服务端就进入CLOSE-WAIT(关闭等待)状态。这时TCP的连接处于半关闭状态,即客户端到服务器这个方向的连接就释放了,即客户端已经没有数据要发送了,但服务器若发送数据客户端仍要接收,也就是从服务器到客户端的连接并未关闭
第三次:如果服务器没有要发送的数据,这时服务器发出连接释放报文,FIN = 1,ack = u + 1,seq = w。这时服务端进入LAST-ACK(最后确认)状态,等待A的确认
第四次:客户端在收到服务端的释放报文后, 必须对此发出确认。确认报文段把ACK置1,确认号ack = w + 1,自己的序号seq = u + 1。然后进入到TIME-WAIT(时间等待)状态。注意这个时候连接还没有释放掉。必须经过事件等待计时器设置的时间后客户端才进入到CLOSED状态。
为什么客户端在TIME-WAIT状态要等待呢?
第一是为了保证客户端发送的最后一个ACK报文能够达到服务端。这最后一个报文有可能会丢失,如果服务器收不到这个报文,会超时重传FIN+ACK报文,如果客户端能在等待事件内收到这个重传的报文,那么客户端就会重新确认一次,重新启动等待计时器。最后都会今日到CLOSED状态,如果不等待一段时间,服务端有可能就收不到确认报文,导致无法进入CLOSED状态
第二是防止上面提到的已失效的连接请求报文出现在本连接中。