TCP联接完善与关掉TCP是一个面向联接的合同,无论哪一方向另一方发送数据之前,都必须先在双方之间构建一条联接。本节将详尽讨论一个TCP联接是怎么完善的以及通讯结束后是怎样中止的。构建一个TCP联接TCP使用三次握手three-wayhandshake合同来构建联接,图3-10描述了三次握手的报文序列。这三次握手为:恳求端(一般称为顾客)发送一个SYN报文段(SYN)指明顾客准备联接的服务器的端口,以及初始顺序号(ISN服务器发回包含服务器的初始顺序号的SYN报文段(SYN)作为应答。同时,将确认号设置为顾客的ISN以对顾客的SYN报文段进行确认(ACK顾客必须将确认号设置为服务器的ISN以对服务器的SYN报文段进行确认(ACK),该报文通知目的主机双方已完成联接构建。发送第一个SYN的一端将执行主动打开(activeopen),接收这个SYN并发回下一个SYN的另一端执行被动打开(passiveopen)。另外,TCP握手合同被悉心设计为可以处理同时打开(simultaneousopen),对于同时打开它仅构建一条联接而不是两条联接。为此,联接可以由任一方或双方发起,一旦联接完善,数据就可以单向对等地流动,而没有所谓的主从关系。

三次握手合同是联接两端正确同步的充要条件。由于TCP构建在不可靠的分组传输服务之上,报文可能遗失、延迟、重复和正序,因而合同必须使用超时和重传机制。假如重传的联接恳求和以前的联接恳请在联接正在构建时抵达,或则当一个联接早已构建、使用和结束以后,某个延后的联接恳求才抵达,还会出现问题。采用三次握手合同(加上这样的规则:在联接构建以后TCP就不再搭理又一次的联接恳求)就可以解决这种问题。三次握手合同可以完成两个重要功能:它确保联接双方做好传输打算,并使双方统一了初始顺序号。初始顺序号是在握手期间传输顺序号并获得确认:当一端为构建联接而发送它的SYN时,它为联接选择一个初始顺序号;每位报文段都包括了顺序号数组和确认号数组,这促使两台机器仅仅使用三个握手报文才能协商好各自的数据流的顺序号。通常来说,ISN随时间而变化,因而每位联接都将具有不同的ISN关掉一个TCP联接TCP联接构建上去后,就可以在两个方向传送数据流。当TCP的应用进程再没有数据须要发送时,就发关掉命令。TCP通过发送控制位FIN=1的数据片来关掉本方数据流,但还可以继续接收数据,直至对方关掉那种方向的数据流,联接就关掉。TCP合同使用更改的三次握手合同来关掉联接,如图3-11所示,即中止一个联接要经过次握手。

linuxtcp命令_linux关闭连接_linux关闭tcp连接命令

这是由于TCP的半关掉(half-close)导致的。因为一个TCP联接是全双工(即数据在两个方向上能同时传递),因而每位方向必须单独地进行关掉。关掉的原则就是当一方完成它的数据发送任务后才能发送一个FIN来中止这个方向联接。当一端收到一个FIN,它必须通知应用层另一端早已中止了那种方向的数据传送。发送FIN一般是应用层进行关掉的结果。从一方的TCP来说,联接的关掉有三种情况:本方启动关掉收到本方应用进程的关掉命令后,TCP在发送完仍未处理的报文段后,发FIN的报文段给对方,且TCP不再受理本方应用进程的数据发送。在FIN曾经发送的数据字节,包括FIN,都须要对方确认,否则要重传。注意FIN占一个顺序号。一旦收到对方对FIN的确认以及对方的FIN报文段,本方TCPFIN进行确认,在等待一段时间,之后关掉联接。等待是为了避免本方的确认报文遗失,防止对方的重传报文干扰新的联接。TCP收到对方发来的FIN报文时,发ACK确认此FIN报文,并通知应用进程联接正在关掉。应用进程将以关掉命令响TCP在发送完仍未处理的报文段后,发一个FIN报文给对方TCP,之后等待对方对FIN的确认,收到确认后关掉联接。

linux关闭连接_linuxtcp命令_linux关闭tcp连接命令

若对方的确认未及时抵达,在等待一段时间后也关掉联接。双方同时启动关掉联接双方的应用进程同时发关掉命令,则双方TCP在发送完仍未处理的报文段后,发送FIN报文。各方TCPFIN前所发报文都得到确认后,发ACK认它收到的FIN。各方在收到对方对FIN的确认后,同样等待一段时间再关掉联接。这称之为同时关掉(simultaneouscloseTCP状态机TCP合同的操作可以使用一个具有11种状态的有限状态机(FiniteStateMachine)来表示,图3-12描述了TCP的有限状态机,图中的圆角方形表示状态,箭头表示状态之间的转换,各状态的描述如表3-2所示。图中用粗线表示顾客端主动和被动的服务器端构建联接的正常过程:顾客端的状态演变用粗虚线,服务器端的状态演变用粗实线。细线用于不常见的序列,如复位、同时打开、同时关掉等。图中的每块状态变换线上均标有“事件/动作”:风波是指用户执行了系统调用(CONNECTCLOSE)、收到一个报文段(SYNRST)、或者是出现了超过两倍最大的分组生命期的情况;动作是指发送一个报文段(SYNACK)或哪些也没有(用“-”表示)。3-12TCP有限状态机。

粗虚线表示顾客的正常路径;粗实线表示服务器的正常路径;细线表示不常见的风波。每位联接均开始于CLOSED状态。当一方执行了被动的联接谓词(LISTEN或主动的联接谓词(CONNECT)时,它便会脱离CLOSED状态。若果此时另一方执行了相对应的联接解释器,联接便构建了,但是状态变为ESTABLISHED何一方均可以首先恳求释放联接,当联接被释放后,状态又回到了CLOSED3-2TCP状态表CLOSED关掉状态,没有联接活动或正在进行LISTEN窃听状态,服务器正在等待联接步入SYNRCVD收到一个联接恳求,仍未确认SYNSENT早已发出联接恳求,等待确认ESTABLISHED联接构建,正常数据传输状态FINWAIT(主动关掉)早已发送关掉恳求,等待确认FINWAIT(主动关掉)收到对方关掉确认,等待对方关掉恳求TIMEDWAIT完成单向关掉,等待所有分组挂掉CLOSING双方同时尝试关掉,等待对方确认CLOSEWAIT(被动关掉)收到对方关掉恳求,早已确认LASTACK(被动关掉)等待最后一个关掉确认,并等待所有分组挂掉正常状态转换我们用图3-13来显示在正常的TCP联接的构建与中止过程中,顾客与服务器所经历的不同状态。

linux关闭连接_linuxtcp命令_linux关闭tcp连接命令

读者可以对照图3-12来阅读,使用图3-12的状态图来跟踪图3-13的状态变化过程,便于明白每位状态的变化:服务器端首先执行LISTEN子句步入被动打开状态(LISTEN),等待顾客端联接;当顾客端的一个应用程序发出CONNECT命令后,本地的TCP实体为其创建一个联接记录并标记为SYNSENT状态,之后给服务器发送一个SYN报文段;服务器收到一个SYN报文段,其TCP实体给顾客端发送确认ACK报文段同时发送一个SYN讯号,步入SYNRCVD状态;顾客端收到SYNACK报文段,其TCP实体给服务器端发送出三次握手的最后一个ACK报文段,并转换为ESTABLISHED状态;服务器端收到确认的ACK报文段,完成了三次握手,于是也步入ESTABLISHED状态。在此状态下,双方可以自由传输数据。当一个应用程序完成数据传输任务后,它须要关掉TCP联接。假定仍由顾客端发起主动关掉联接。顾客端执行CLOSE子句,本地的TCP实体发送一个FIN报文段并等待响应的确认(步入状态FINWAIT服务器收到一个FIN报文段,它确认顾客端的恳求发回一个ACK报文段,步入CLOSEWAIT状态;顾客端收到确认ACK报文段,就转移到FINWAIT状态linux系统好用吗,此时联接在一个方向上就断掉了;服务器端应用得到通告后,也执行CLOSE子句关掉另一个方向的联接,其本地TCP实体向顾客端发送一个FIN报文段,并步入LASTACK态,等待最后一个ACK确认报文段;顾客端收到FIN报文段并确认,步入TIMEDWAIT状态,此时双方联接均早已断掉,但TCP要等待一个倍报文段最大生存时间MSLMaximumSegmentLifetime),确保该联接的所有分组全部消失,以避免出现确认遗失的情况。

linux关闭连接_linuxtcp命令_linux关闭tcp连接命令

当定时器超时后,TCP删掉该联接记录,返回到初始状态(CLOSED服务器收到最后一个确认ACK报文段linux关闭tcp连接命令,其TCP实体便释放该联接,并删除联接记录,返回到初始状态(CLOSED同时打开:虽然发生的可能性极小,两个应用程序同时彼此执行主动打开的情况还是可能的。每一方必须发送一个SYN,且这种SYN必须传递给对方。这须要每一方使用一个对方周知的端口作为本地端口。诸如,主机中的一个应用程序使用本地端口7777,并与主机的端口8888执行主动打开。主机中的应用程序则使用本地端口8888linux关闭tcp连接命令,并与主机的端口7777执行主动打开。TCP意设计为了可以处理同时打开,对于同时打开它仅构建一条联接而不是两条联接(其他的合同族,最突出的是OSI传输层,在这些情况下将构建两条联接而不是一条联接)。当出现同时打开的情况时,状态演变与图3-13所示的不同。两端几乎在同时发送SYN,并步入SYN_SENT状态。当每一端收到SYN时,状态变为SYN_RCVD,同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN及相应的ACK时,状态都演变为ESTABLISHED3-14显示了这种状态演变过程。

3-14同时打开期间报文段的交换一个同时打开的联接须要交换个报文段,比正常的三次握手多一个。据悉,要注意的是我们没有将任何一端称为顾客或服务器,由于每一端既是顾客又是服务器。同时关掉:正常情况下都是由一方(一般但不总是顾客方)发送第一个FIN执行主动关掉,但双方都执行主动关掉也是可能的,TCP合同也容许这样的同时关掉。3-12中,当两端应用层同时发出关掉命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这将造成双方各发送一个FIN,两个FIN经过网路传送后分别抵达另一端。收到FIN后,状态由FIN_WAIT_1演变到CLOSING,并发送最后的ACK。当收到最后的ACK时,状态变化为TIME_WAIT3-15总结了这种状态的变化linux查看端口占用,从图中可以看出同时关掉与正常关掉使用的报文段交换数量相同。3-15同时关掉期间的报文段交换服务方打开:从LISTENSYN_SENT的变革是正确的,它由服务器端主动发出SYN报文段,但BerkeleyTCP软件并不支持它。

Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复