【TCP】 为什么3次握手 4次挥手

1 三次握手

TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP 协议提供可靠的连接服务,连接是通过三次握手🤝进行初始化的。三次握手🤝的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。由此我们来对应客户端与服务器之间的建立连接:

  • 第一次握手🤝: 客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN=1,同时随机生成初始序列号 seq=x,此时,客户端进程进入了 SYN-SENT状态,等待服务器的确认。
  • 第二次握手🤝: 服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1SYN=1,确认号是ack=x+1,同时也要为自己随机初始化一个序列号 seq=y,此时,服务器进程进入了SYN-RCVD状态,询问客户端是否做好准备。
  • 第三次握手🤝: 客户端进程收到确认后,还要向服务器给出确认。确认报文的ACK=1ack=y+1,此时,连接建立,客户端进入ESTABLISHED状态,服务器端也进入ESTABLISHED状态。

从上图可以很清晰的看出,如果不是三次握手,比如2次,客户端SYN发次的那一次握手如果被劫持或者在某个网络节点中长时间的滞留,当Server收到滞留的报文后,发起的连接对客户端来说都是无效的,导致Server端很多半连接资源【syns queue】被占用,如果脏链接占用过多会导致无法服务。 采用三次握手的办法就是为了防止上述这种情况的发生,比如就在刚才的情况下,客户端不会向服务端发出确认的请求,服务端会因为收不到确认的报文,就知道客户端并没有要建立连接,那么服务端也就不会去建立连接,这就是三次握手的作用。

 

2 四次挥手

  • 第一次挥手👋: 客户端进程发出连接释放FIN报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=x,此时,客户端进入FIN-WAIT-1(终止等待1)状态。
  • 第二次挥手👋: 服务端进程收到连接释放FIN报文,发出确认ACK报文,ACK=1ack=x+1,并且带上自己的序列号seq=y,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。此时,服务端通知高层的应用进程,客户端向服务端的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务端若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。客户端收到服务端的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文,在这之前依然可以接收服务端发送过来的最后的数据。
  • 第三次挥手👋: 服务端将最后的数据发送给客户端完成后,就向客户端发送连接释放FIN报文,FIN=1ack=x+1,此时的序列号为seq=z,此时,服务端就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手👋: 客户端接收到服务端的连接释放FIN报文后,必须发出确认报文,ACK=1ack=z+1,而自己的序列号是seq=x+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。此时服务端收到客户端发送过来的确认报文,就立即撤销自己的传输控制块TCB,进入CLOSED状态,注意此时的TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,客户端没有收到服务端发来的任何数据,证明服务端已正常关闭,此时客户端会撤销相应传输控制块TCB后,进入CLOSED状态。至此,TCP的连接才真正的断开了。(服务端结束TCP连接的时间要比客户端稍微早一些)

 

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工 模式,这就意味着,在客户端想要断开连接时,客户端向服务端发送FIN报文,只是表示客户端已经没有数据要发送了,但是这个时候客户端还是可以接收来自服务端的数据。

当服务端接收到FIN报文,并返回ACK报文,表示服务端已经知道了客户端要断开连接,客户端已经没有数据要发送了,但是这个时候服务端可能依然有数据要传输给客户端。

当服务端的数据传输完之后,服务端会发送FIN报文给客户端,表示服务端也没有数据要传输了,服务端同意关闭连接,之后,客户端收到FIN报文,立即发送给客户端一个ACK报文,确定关闭连接。在之后,客户端和服务端彼此就愉快的断开了这次的TCP连接。​​​​​​​

为什么服务端的ACK报文和FIN报文都是分开发送的,但是在三次握手的时候却是ACK报文和SYN报文是一起发送的,因为在三次握手的过程中,当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是在关闭连接时,当服务端接收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,你发的FIN报文我收到了,只有等到服务端所有的数据都发送完了,才能发送FIN报文,因此ACK报文和FIN报文不能一起发送。所以断开连接的时候才需要四次挥手来完成。

解释的是2、3挥手不能合并的原因;有点牵强。

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页