TCP是面向连接的协议,运输连接是用于传输TCP报文的。TCP运输的建立和释放是每一次面向连接的通信中必不可少的过程,同时也是在面试过程中必被提问的问题之一。
TCP运输连接有三个阶段,分别是:连接建立阶段、数据传输阶段、连接释放阶段。
一:TCP的连接建立
TCP连接建立的过程叫做握手,业内也称为三次握手,但笔者在阅读有些专业书籍时,发现有不少作者提出应该译为“三报文握手”。因为在TCP连接建立中的握手是客户端和服务器端之间通过交换三个报文段从而建立接连,并不是通过握手三次而建立连接。为此,笔者特意去查看了TCP标准文档,发现文档中对于连接建立的描述使用的是 three way handshake,那根据标准文档的用法似乎译为三报文握手更为贴切。这里我们就不做文字游戏了,业内习惯称为三次握手,我们知道其中的差异就行。
接下来我们通过笔者亲自提笔画的不能说鬼斧神工,只能说难以直视的TCP连接建立流程图来了解三报文握手的全过程,以及在连接建立的过程中客户端和服务器端的不同状态。
如图,主机A为TCP客户进程,主机B为TCP服务器进程。且图中主机A为主动打开连接,主机B为被动打开连接。
- 客户进程和服务器进程都处于关闭状态(SLOSED)。
- 主机B的TCP服务器进程首先创建传输控制模块TCB,等待接收主机A的连接请求,同时进入监听状态(LISTEN)。
- 主机A的TCP客户进程也创建传输控制模块TCB,并向主机B发送连接请求报文段。报文段中的参数为:同步控制位SYN=1,初始序号seq=x,同时TCP规定SYN报文段不能携带数据,但要消耗一个序号。此时,主机A的客户进程进入同步已发送状态(SYN-SENT)。【关于参数同步控制位SYN、序号seq等所代表的含义,笔者将会在TCP报文相关知识分享的篇幅中进行讲解,链接:敬请期待…………】
- 主机B的服务器进程收到连接请求报文段后,若同意建立连接,则向主机A发送一个确认报文。报文中的参数为:同步控制位SYN=1,确认控制位ACK=1,初始序号seq=y,确认号ack=x+1。同样,这个报文段也不能携带数据,但要消耗一个序号。此时,主机B的服务器进程进入同步收到状态(SYN-RCVD)。
- 主机A的客户进程收到主机B的确认报文后,再向主机B发送确认报文。报文中的参数为:确认控制位ACK=1,序号seq=x+1,确认号ack=y+1。TCP规定:ACK报文段可以携带数据,携带数据则消耗一个序号,不携带数据则不消耗序号。此时,主机A的客户进程进入连接建立状态(ESTABLISHED)。
- 主机B的服务器进程收到主机A的确认后,进入连接建立状态(ESTABLISHED)。
二:TCP的连接释放
数据传输结束之后,进程双方需要通过四报文挥手来释放连接。同样,笔者查阅TCP标准文档发现对四报文挥手的描述为 four way wavehand,因此称为四报文挥手,但业内习惯称为四次挥手。
如图,主机A为TCP客户进程,主机B为TCP服务器进程。双方最初均为连接建立状态(ESTABLISHED)。
- 主机A的应用进程发出连接释放报文段,并停止发送数据,主动关闭连接。报文段参数为:终止控制位FIN=1,序号seq=u(为前面已经传输过的数据的最后一个字节的序号加1)。但TCP规定FIN报文不能携带数据,但序号消耗一个序号。此时,主机A的客户进程进入终止等待1状态(FIN-WAIT-1)。
- 主机B收到来自主机A的连接释放报文段后立即发出确认报文。报文参数为:确认控制位ACK=1,确认号ack=u+1,序号seq=v(为前面已经传输过的数据的最后一个字节的序号加1),然后进入关闭等待状态(SLOSE-WAIT)。此时,TCP连接处于半关闭状态,主机A没有数据传输至主机B;但主机B若还需传输数据至主机A,主机A需要接收。因此,半关闭状态即为主机A到主机B的连接已经关闭,而主机B到主机A的连接并未关闭。
- 主机A收到主机B的确认报文后,进入终止等待2状态(FIN-WAIT-2),等待主机B发出连接释放报文段。
- 主机B已经没有数据要发送给主机A了,因此,主机B发出连接释放报文段。报文参数为:终止控制位FIN=1,确认控制位ACK=1,确认号ack=u+1,序号seq=w(为最好传输数据的最后一个字节加1)。此时,主机B进入最后确认状态(LAST-ACK)。
- 主机A收到主机B的连接释放报文段后,向主机B发出确认报文。报文参数为:确认控制位ACK=1,序号seq=u+1,确认号ack=w+1。此时,主机A进入时间等待状态(TIME-WAIT)。
- 主机B收到主机A发送的确认报文段后, 撤销相应的传输控制块TCB,进入关闭状态(SLOSED)。
- 主机A在等待2MSL后(MSL:Maximum Segment Lifetime,最长报文段寿命),撤销相应的传输控制块TCB,进入关闭状态(SLOSED)。
三:常见的关于TCP连接的拓展面试问题
(1)三报文握手能否改成两报文握手? 或 为什么主机A最后还要再向主机B发送一次确认?
这是为了防止主机A发送的已失效的连接请求报文段突然又传送到了主机B,因而产生错误。
一般,主机A发出连接请求报文段,就会出现三种情况。
情况一:连接请求报文段正常被主机B接收,并且发回确认报文段,双方建立了连接,数据传输完成之后,释放了连接。
情况二:连接请求报文段在传输的过程中丢失,导致主机B并未收到连接请求报文,因此也不会发回确认报文。主机A在一定的时间内没有收到确认报文,就判断出报文丢失,于是再重发一次连接请求报文,建立了连接。
情况三:连接请求报文在传输的过程中没有丢失,仅仅是因为网络问题导致在某个节点出现的迟滞,以致延误到连接释放之后才到达主机B。而主机A并不知道这个连接请求报文出现迟滞,意味是丢失,于是重传了一个连接请求报文,并建立了连接。但在数据传输结束之后,第一个本来已经被认为丢失的连接请求报文到达了主机B,而主机B误认为主机A又发起了连接请求,于是又向主机A发送确认报文,同意建立连接。如果两报文握手,那么主机B发出确认,连接又建立了。
因此,三报文握手改为两报文握手是不行的。在情况三中,即使出现这样的问题,三报文握手机制下,主机B收到迟滞的连接请求,发回确认报文,但主机A并不会理睬主机A而发回确认报文,因此连接不会建立,资源也不会浪费。
(2)TCP三报文握手能否改成四报文握手?
可以,但没有必要,互联网主打的就是一个效率。改成四报文握手就是将主机B发送的确认报文拆分成两个报文发送。即先发送一个确认报文段(报文参数ACK=1,ack = x +1),在发送一个同步报文段(报文参数SYN=1,seq=y)。
(3)为什么主机A在进入时间等待状态(TIME-WAIT)之后,需要等待2MSL的时间?
第一:保证主机A发送的最后一个ACK报文能够到达主机B。若主机A在发送完最后一个ACK报文段之后立即进入关闭状态,而这个ACK报文段有可能在传输的过程中丢失,而导致主机B一直收不到主机A发送的确认报文段,因此无法正常进入关闭状态。文章来源:https://www.toymoban.com/news/detail-774223.html
第二:防止已失效的连接请求报文段出现在连接中。主机A在发送完最后一个确认报文段之后,经过2MSL时间的等待,就可以使本来连接持续的时间内所产生的所有报文段都从网络中消失,这样就可以保证新的连接请求中不会出现旧的连接请求报文段。文章来源地址https://www.toymoban.com/news/detail-774223.html
到了这里,关于TCP的连接建立与释放的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!