TCP的三次握手与四次挥手

三次握手与四次挥手

三次握手和四次挥手是人类抽象定义的概念,实质是描述TCP建立连接的过程。
三次握手和四次挥手发生在传输层,传输层有TCP(传输控制协议)和UDP(用户数据报协议),先介绍简单下这两种协议。

UDP是无连接、不可靠的一种连接方式,即是说通讯前不需要建立连接,便直接传输数据,但不能保证消息一定会达到目的端,没有超时和重传功能。但有处理速度快的优点,所以通常音频、视频的普通数据在传送时使用UDP较多,DNS、DHCP、IGMP等也是使用UDP协议。

TCP是一种面向连接、可靠、基于字节流的传输层通信协议。还有流量控制、拥塞控制等功能。
当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段来传送。为了保证报文传输的可靠,就给每个包一个序号(数据包),之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP,然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);
同时在传送过程中在数据正确性与合法性上、保证可靠性上、在流量控制上、在拥塞控制上均有相关的控制机制。
三次握手说的就是上面TCP建立连接的过程。

TCP三次握手(面向连接)
为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。即在通信之前,会先通过三次握手机制来确认两端口之间的连接是否可用。 UDP则直接传。

示意图:

符号解释

seq:序号    ack:确认序号     ACK:确认    SYN:同步

简说:

1. 发送端标有SYN的数据包发给接收端。

2. 接收端接到数据包,返回确定等信息给发送端。

3. 发送端收到接收端的确认信息,再发送确认报文给接收端说知道接收端你已经准备好了

为什么要三次握手

三次握手的目的是建立可靠的通信信道,即是说数据的发送与接收双方都能确认是正常的,可靠的。

第一次,server确认了client的发送正常

第二次,client确认了自己的发送、接收正常与对方也能发收正常,server确认了自己接收正常与对方发正常

第三次,client确认了自己与对方的发收正常,server确认了自己与对方的发收正常。

所以说三次握手能确认双方收发都能正常。

 为什么还要发最后一次确认呢

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

如果使用两次握手建立连接:如果有一个场景,客户端发送了第一个请求连接并且没有丢失,而是在某些网络结点中滞留了,由于TCP客户端迟迟没有收到确认报文,以为服务端没有收到,此时重新向服务器发送这条报文,然后能成功建立连接,传输数据,然后关闭连接。

此时那条滞留的报文,本来应该失效的,到达了服务端,两次握手机制会让双方再次建立连接,这就造成不必要的错误和资源的浪费。

如果采用的是三次握手,那条失效的报文传来,服务端接受到了那条报文并回复确认报文,但客户端不会再次发出确认,由于服务端收不到确认,就建立不起连接了。

四次挥手(改进的三次握手)

完成通信后,通过四次挥手来释放连接。

数据传输完毕后,双方都可以发出释放连接的请求。

简说:

如客户端发出释放连接的请求,

待对方确认后进入半关闭状态。

服务端没有数据再发送时,发出释放连接通知。

客户端确认后就关闭TCP连接。

1. 一次挥手:当客户端(也可以是服务端)没有数据要发送时,发送FIN报文给服务端,表示没有数据发送了,客户端进入FIN_SAIT_1状态。

2. 二次挥手:服务端收到客户端的FIN报文段,回一个ACK确认报文段。客户端进入FIN_WAIT_2状态,服务端告诉客户端我也没有数据要发了,可以关闭连接了。

3. 三次挥手:服务端向客户端发送FIN报文段,请求关闭连接,同时服务端进入CLOSE_WAIT状态。

4. 四次挥手:客户端收到服务端发送的FIN报文段,向服务端发送ACK报文段,然后服务端进入TIME_WAIT状态;服务端收到客户端的ACK报文段以后,就关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,客户端也可以关闭连接了。

 为什么要四次挥手

要等双方的数据都收发完才能关闭连接

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。

  • FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。(主动方)
  • FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。(主动方)
  • CLOSE_WAIT:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。(被动方)
  • LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)
  • TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FINWAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)
  • CLOSED: 表示连接中断。

参考与推荐:

1、TCP/IP详解

原文地址:https://www.cnblogs.com/lisen10/p/10700202.html