TCP三次握手/四次挥手

一、三次握手

  所谓三次握手,就是建立TCP连接时所需要的三个步骤。

其中,seq表示数据包本身的序列号,ack表示希望对方发送的那个数据包的序列号。

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给server,client进入SYN_SENT状态,等待Server确认。

(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client和Server之间就可以传输数据了。

 

 

二、四次挥手

(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态

(2)第二次挥手:SERVER收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSED_WAIT状态

(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态

(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

 

 

三、常见问题

1、建立连接过程中,为什么TCP客户端还要发送一次确认?

主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用两次握手建立连接,假设有这样一种场景,客户端发送第一个请求并且没有丢失,只是用为在网络节点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,从后客户端和服务器经过两次握手完成连接,传输数据,再关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器在此建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接收到了那条失效的报文并回复了确认报文,但是客户端不会再次发送确认,由于服务器收不到确认,就知道客户端并没有请求连接。

 

2、为什么连接的时候是三次握手,关闭的时候却是四次挥手?

因为TCP连接是双向的,当服务器收到客户端的FIN报文之后,并不会立即关闭Socket,只会先回复一个ACK报文表明已经收到了FIN报文,当服务器所有的数据都发送完毕,才会回复客户端FIN报文,客户端回复ACK报文,确认已收到FIN报文,自此断开连接。

 

3、为什么断开连接,客户端最后还要等待2MSL?

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

 

posted @ 2019-08-04 20:02  十月围城丶  阅读(75)  评论(0)    收藏  举报