美文网首页Android基础知识
【网络】TCP三次握手和四次挥手

【网络】TCP三次握手和四次挥手

作者: 秀叶寒冬 | 来源:发表于2019-06-26 20:52 被阅读10次

    1 TCP简介

    TCP协议全称: 传输控制协议, 顾名思义, 就是要对数据的传输进行一定的控制。该协议处于7层协议中的传输层。

    TCP协议报文如图1.1所示

    图1.1 TCP报文

    在上述图中,有几个英文单词,分别表示的意思如下(摘自《计算机网络安全教程》):

    • URG:是否使用紧急指针。0为不使用,1为使用。
    • ACK:请求-应答状态。0为请求,1为应答。
    • PSH:以最快的速度传输数据。
    • RST:连接复位,首先断开连接然后重建。
    • SYN:同步连接序号,用来建立连接。
    • FIN:结束标志。0表示结束连接请求,1表示结束连接。
    • ack:表示下一个数据包的编号

    2 TCP三次握手

    TCP三次握手过程如下图2.1所示:

    图2.1 TCP三次握手过程示意图

     

    • 第一次握手:客户端向服务端发送连接请求,SYN=1,seq=x,ACK=0(请求)。此时客户端进入SYN-SENT(同步已发送)状态。
    • 第二次握手:服务器收到请求报文后,同意建立连接,则发回确认包,确认包中包含SYN=1,ACK=1(应答),seq=y,ack=x+1。此时服务端进入SYN-RCVD(同步收到)状态。
    • 第三次握手:客户端接收到确认包后,给服务端发送ACK=1(应答,表示已经接收到)。此时客户端和服务端都进入ESTABLISHED(已建立连接)状态。

    总结:三次挥手可以形象地表示为:A向B请求(ACK=0)连接,B如果同意连接则回答(ACK=1)A说同意连接,A接收到B的信息后也回答(ACK=1)道:我接收到你的同意回复了。这样三次握手完成。

    3 TCP四次挥手过程

    四次挥手过程如下图3.1所示


    图3.1 TCP四次挥手过程示意图

     

    • 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
    • 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    • 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
    • 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
    • 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
    • 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

    总结:四次挥手过程可以简短形象的用以下文字来表述:A想要断开连接,因此向B发送了断开连接请求,然后A进入等待1状态;B接收到请求后就发送消息询问A是否确定断开连接,然后B就进入关闭等待状态;A接收到询问消息后就进入等待2状态,等待B发送最后的数据;B此时不等A发送最终的确认消息,而是将未发送完的数据发送给A,并向A发送结束连接报文,发送完后B就进入最终确认状态;A接收到最后的数据后,就发送最终确认关闭连接的消息,然后自己进入时间等待状态;B接收到最终确认后就断开了TCP连接;A等待一段时间后也自己断开了TCP连接。

    4 常见面试问题

    • 【问题1】为什么连接的时候是三次握手,关闭的时候是四次握手?

    因为连接时只需要最少三次握手就能确定服务端和客户端是否建立连接;而关闭时,当客户端请求断开连接时,服务端接收到断开连接请求时,可能还有数据未传输完,因此不能立即断开连接,而是给客户端发送确认报文,表示你的请求我已经收到了,等待数据传输完成后再给客户端发送断开连接报文,然后客户端发送最终确认消息,所以关闭时是四次握手。

    • 【问题2】如果已经建立了连接,但是客户端突然出现故障了怎么办?

    TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    • 【问题3】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

    虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

    相关文章

      网友评论

        本文标题:【网络】TCP三次握手和四次挥手

        本文链接:https://www.haomeiwen.com/subject/acihcctx.html