三次握手
- 客户端向服务端发出连接请求报文,报文首部同步位SYN=1,随机初始序列号seq=x,此时客户端进程进入了
同步已发送状态
- 服务器收到请求报文后,如果同意连接,则发出确认报文,确认报文中包含ACK=1,SYN=1,确认号ack=x+1,同时自己要生成一个随机序列号seq=y,进入
同步收到状态
- 客户端收到报文后,还要给出确认报文,ACK=1,ack=y+1,然后进入
连接状态。
为什么要3次握手呢?
如果客户端发送的一个连接请求,因为网络延迟失效,知道那么当这个失效的连接请求达到服务端后,服务端误以为请求有效,依然会返回确认报文,并进入连接状态,但是因为请求是失效的,所以客户端不会对服务端返回的报文进行响应,这样就导致服务器一直处于连接状态,等待客户端发送数据,造成资源浪费。如果采用三次握手,只有在收到客户端的确认报文后,整个TCP连接才算建立。
四次挥手
- 客户端发出连接释放报文,停止发送数据,报文首部FIN=1,seq=u,客户端进入等待状态1,FIN-WAIT-1。
- 服务端收到连接释放报文后,返回一个确认报文,ACK=1,ack=u+1,带上自己的序列号seq=v,此时服务器端进入关闭等待(CLOSE-WAIT)状态,这时处于半关闭状态,客户端不再发送数据,但是服务端要继续把未发送完的数据发送完毕。
客户端收到服务端的确认报文后,进入FIN-WAIT-2状态,等待服务端发送连接释放报文。 - 服务端将最后的数据发送完毕后,向客户端发送连接释放报文,FIN=1,ack=u+1,此时,服务器进入LAST-ACK(最后确认)状态,等待客户端的确认。
-
客户端收到服务端的链接释放报文后,发出确认,ACK=1,ack=w+1,客户端进入TIME-WAIT(时间等待)状态,必须过一段时间后,才进入CLOSED状态。
四次挥手.png
为什么要四次挥手?
服务器端在收到客户端的FIN报文后,并不会立即关闭SOCKET,因为此时服务器可能有些数据还未发送完成,因此只能先回应一个ACK报文,告诉客户端收到了释放报文,等到数据发送完成后,才向客户端发送FIN 报文。
网友评论