一、三次握手

首先,我们假设客户端与服务器均处于未连接状态,并且是客户端主动向服务器请求建立连接。TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接

首先要明白位码的概念,位码即tcp标志位:有6种标示:SYN(synchronous建立联机)、 ACK(acknowledgement 确认) 、PSH(push传送、ST(reset重置)、 URG(urgent紧急) 、Sequence number(顺序号码) Acknowledge number(确认号码)。

三次握手的过程如下:
  • 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k)时服务器 进入SYN_RECV状态
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手。 完成三次握手,客户端与服务器开始传送数据

3分钟看懂什么是三次握手/四次挥手


二、四次挥手

TCP连接的释放就是俗称的四次挥手,它和三次握手是正反面的应用,一个拿来开始,一个则是结束。假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。

Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭

四次挥手的过程较三次挥手复杂,具体原因我们后面会谈到,先看看它是怎样一个过程:

数据传输结束后,通信的双方都可释放连接,A和B都处于ESTABLISHED状态。(A、B连接建立状态ESTABLISHED——A终止等待1状态FIN-WAIT-1——B关闭等待状态CLOSE-WAIT——A终止等待2状态FIN-WAIT-2——B最后确认状态LAST-ACK——A时间等待状态TIME-WAIT——B、A关闭状态CLOSED)

  • A的应用进程先向其TCP发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
  • B收到连接释放报文段后即发出确认报文段,(ACK=1,确认号ack=u+1,序号seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放。
  • A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
  • B没有要向A发出的数据,B发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),B进入LAST-ACK(最后确认)状态,等待A的确认。
  • A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。

整个流程如下:

3分钟看懂什么是三次握手/四次挥手


三、常见问题

1. 为什么要三次握手?

客户端向服务器发送了第一条请求报文,但是该报文并未在网络中被丢弃,而是长时间阻滞在某处,而客户端收不到服务器确认,以为该报文丢失,于是重新发送该报文,这次的报文成功到达服务器,如果不使用三次握手,则服务器只需对该报文发出确认,就建立了一个连接。

而在这个连接建立,并释放后,第一次发送的,阻滞在网络中的报文到达了服务器,服务器以为是客户端又重新发送了一个连接请求(实际上在客户端那里,该连接早已失效),就又向客户端发送一个确认,但客户端认为他没有发送该请求报文,因此不理睬服务器发送的确认,而服务器以为又建立了一个新的连接,于是一直等待A发来数据,造成了服务器资源的浪费,并且会产生安全隐患。因此,若使用三次握手机制,服务器发送了该确认后,收不到客户端的确认,也就知道并没有建立连接,因此不会将资源浪费在这种没有意义的等待上。

2.为什么要四次挥手

根本原因是,一方发送FIN只表示自己发完了所有要发的数据,但还允许对方继续把没发完的数据发过来。举个例子:A和B打电话,通话即将结束后,A说“我没啥要说的了”,B回答“我知道了”,但是B可能还会有要说的话,A不能要求B跟着自己的节奏结束通话,于是B可能又巴拉巴拉说了一通,最后B说“我说完了”,A回答“知道了”,这样通话才算结束。

3. 为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。


相关文章:

  • 2021-10-30
  • 2021-11-12
  • 2021-07-23
  • 2021-05-16
  • 2021-05-15
  • 2022-01-10
  • 2021-06-25
  • 2022-12-23
猜你喜欢
  • 2021-04-21
  • 2021-07-06
  • 2022-01-28
  • 2021-07-25
  • 2021-08-01
  • 2021-11-11
  • 2021-10-26
相关资源
相似解决方案