TCP的三次握手和四次挥手详解

来源:互联网 发布:300451 创业软件 编辑:程序博客网 时间:2024/05/16 04:09

          TCP协议的三次握手和四次挥手是常考的面试题。在此我们来分析一下其过程。

          当谈到TCP协议的三次握手和挥手时,可以理解那时客户端和服务器端的建立连接和解除连接的过程。

  一、TCP的概念:

         TCP(Transmission Control Protocol 传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协 议,由IETF的RFC 793定义。简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。用户数据报议,(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

      tcp协议首部:

        

二、TCP的三次握手

        先来看看三次握手的流程:以下标出来的就是所谓的三次。

        

  我们来详细的来分析一下其三次的过程:

         第一次:首先客户端发送连接请求报文段,将SYN位置为1,seq(Sequence Number)为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;SYN (同步序列编号);

         第二次:服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Ack确认帧为x+1即为客户端发来的(seq+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Seq为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

         第三次:客户端收到服务的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手;

三、TCP的四次挥手

        tcp四次挥手,由于TCP连接是全双工的,因此每个方向都必须单独进行关闭;

       我们来看看上图中所标出的四次过程;可以模拟为下面的场景:

   

         第一次:主机1(可以使客户端,也可以是服务器端),向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1等待状态;这表示主机1没有数据要发送给主机2了;

         第二次:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,主机1进入FIN_WAIT_2等待状态;主机2告诉主机1,我“同意”你的关闭请求;

         第三次主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;

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

      

         如果还不理解四次挥手的过程,那么看下面一段:

          1、client向Server发送消息 FIN“我没有数据要发给你了,我要结束”;

          2、Server收到client发来的消息,向主机1回复 ACK“你的消息我收到了,但是我还没准备好,你等我消息吧”这个时候client就进入FIN_WAIT状态,继续等待Server端的FIN报文。

          3、当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。

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

 问题:  

1、主动发起关闭连接的操作的一方将达到TIME_WAIT(即上图的计时等待)状态,而且这个状态要保持

Maximum Segment Lifetime的两倍时间。为什么要这样做而不是直接进入CLOSED状态?

原因有二:
       一、保证TCP协议的全双工连接能够可靠关闭;

       二、保证这次连接的重复数据段从网络中消失;

先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到

Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与

重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这

样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入

CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的

连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是

还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在

网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协

议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的

新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有

数据都从网络中消失。

2、为什么连接的时候是三次握手,关闭的时候却是四次握手?
     因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
0 0