第5章 运输层

1. 运输层概述

1.1 运输层的功能

运输层向应用层提供通信服务。运输层提供应用进程间的逻辑通信。网络层为主机之间的通信提供服务,而运输层则在网络层的基础上,为应用进程之间的通信提供服务。

运输层还要对收到的报文进行差错检测。

注意,运输层的逻辑通信信道对上层的表现因运输层使用的不同协议而有很大差别。

1.2 端口

1.2.1 端口的起源

复用:发送方不同的应用进程都可以使用同一个运输层协议传送数据。

分用:接收方的运输层在剥去报文首部后能够把这些数据正确交付目的应用进程。

显然,给应用层的每个应用进程赋予一个非常明显的标志是至关重要的。

问题:

1. 计算机操作系统所指派的进程标识符无法标志运行在应用层的各种应用进程,因其种类繁多且格式不同。

2. 无法将一个特定机器上运行的特定进程作为互联网通信的最后终点,因为进程的创建和撤销都是动态的。

解决办法:

在应用层和运输层之间的界面上,设置一个特殊的抽象的“门”。应用进程的发送和查找都必须通过这个门,此门即为通信的抽象终点————协议端口(protocol port),简称端口(port)。

1.2.2 端口的工作机制

每个端口用一个称为端口号(port number)的正整数来标志。主机的操作系统提供了接口机制,使得进程能够通过这种机制找到所要找的端口。

当应用层要发送数据时,应用进程就把数据发送到适当的端口,然后运输层从该端口读取数据,进行后续处理。当运输层收到对方主机发来的数据时,就把数据发送到适当的端口,然后应用进程就从该端口读取这些数据。显然,端口必须有一定容量的缓存来暂时存放数据。

在UDP和TCP的首部格式中,都有源端口和目的端口这两个重要字段。这两个端口就是运输层和应用层进行交互的地点。

1.2.3 端口的格式

TCP/IP的运输层使用16位的端口号。端口号只具有本地意义,在互联网不同计算机中,相同的端口号没有关联。

互联网上的计算机通信是采用客户-服务器方式。客户在发起通信请求时,必须先知道对方服务器的IP地址(找目的主机)和端口号(找目的进程)。因此运输层的端口号分为以下两大类。

(1)服务器使用的端口号

        a. 熟知端口号(wellknown port number),数值为0~1023

        b. 登记端口号,数值为1024~49151

(2)客户端使用的端口号

        动态分配,通信结束后收回,数值为49152~65535

2. 用户数据报协议UDP(User Datagram Protocol)

2.1 UDP的特点

(1)无连接

(2)不可靠交付

(3)面向报文

        UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界,在添加首部后就向下交付IP层。

因此,应用程序必须选择合适大小的报文。报文太长则需要分片,太短则使IP首部相对长度太大,都会降低IP层效率。

(4)没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低,对某些实时应用很重要(IP电话、实时视频会议等)。

(5)支持一对一、一对多、多对一和多对多的交互通信

(6)首部开销小

2.2 UDP的首部格式

2.2.1 UDP首部各字段的意义

(1)源端口:源端口号。在需要对方回信时选用,不需要时可用全0。

(2)目的端口:目的端口号。在终点交付报文时必须使用,若接收方UDP发现收到报文中的目的端口号不正确,则丢弃该报文,并由网际控制报文协议ICMP发送“端口不可达”差错报文给发送方。

(3)长度:UDP用户数据报的长度,最小值为8(仅有首部)。

(4)检验和:检测UDP用户数据报在传输中是否有错,有错就丢弃。

2.2.2 计算检验和

在计算检验和时,要在UDP用户数据报之前临时增加12个字节的伪首部,伪首部既不向下传送也不向上递交。其中第3字段是全零,第4字段是IP首部中协议字段的值。对于UDP,此协议字段值为17.。

(1)发送方生成检验和

        a. 将检验和字段置为全0。

        b. 把伪首部以及UDP用户数据报整理为16位字串,若UDP数据部分为奇数字节,则填入一个          全零字节(不发送)。

        c. 按二进制反码计算出这些16位字的和,写入检验和字段。

(2)接收方检验检验和

        将UDP用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16位字的和。若无差错则结果为全1,否则就表明有差错。

3. 传输控制协议TCP(Transmission Control Protocol)

3.1 TCP的特点

(1)面向连接

(2)一对一

(3)可靠交付

(4)全双工通道

(5)面向字节流

        流(stream):流入到进程或从进程流出的字节序列。

        面向字节流:TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有大小关系。TCP并不关心应用进程一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞程度,来决定一个报文段应包含多少个字节。

3.2 TCP的连接

TCP把连接作为最基本的抽象。

TCP连接的端点是套接字。

套接字socket=(IP地址:端口号)

例如,若IP地址是192.3.4.5而端口号是80,那么得到的套接字就是(192.3.4.5:80)。

每一条TCP连接唯一地被通信两端的两个端点(即套接字对socket pair)所确定。

TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}

同一个IP地址可以有多个不同的TCP连接,而同一个端口号也可以出现在多个不同的TCP连接中。

3.3 TCP报文段的首部格式

TCP的全部功能都体现在它首部中各字段的作用。因此,只有弄清TCP首部各字段的作用才能掌握TCP的工作原理。

(1)源端口和目的端口:源端口号和目的端口号。

(2)序号:本报文段所发送数据的第一个字节的序号。因为TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,因此整个要传送的字节流的起始序号必须在连接建立时设置。序号范围是[0,2^32-1],共2^32个序号。序号增加到2^32-1后,下一序号就又回到0。也就是说,序号使用mod 2^32运算。

(3)确认号:期望收到对方下一个报文段的第一个数据字节的序号。若确认号=N,则表明到序号N-1为止的所有数据都已正确收到。

(4)数据偏移:TCP报文段的数据起始处与TCP报文段的起始处的距离。由于首部中有长度可变的选项字段,因为数据偏移字段是必要的。数据偏移的单位是32位字(4字节)。由于四位二进制数最大能表示15,因此数据偏移的最大值是60字节,这也是TCP首部的最大长度(即选项长度不能超过40字节)。

(5)保留:保留为今后使用,目前置为0。

以下(6)~(11)为6个控制位,用来说明本报文段的性质。

(6)紧急URG(URGent):当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不要按原来的排队顺序传送。

(7)确认ACK(ACKnowledgment):仅当ACK=1时确认号字段才有效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1。

(8)推送PSH(PuSH):当PSH=1时,接收方收到报文段就尽快交付接受应用进程,而不再等到整个缓存都填满了后再向上交付。

(9)复位RST(ReSeT):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立运输连接。

(10)同步SYN(SYNchronization):在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在相应的报文段中使SYN=1和ACK=1。

(11)终止FIN(FINish):当FIN=1时,表明此报文段的发送方数据已发送完毕,并要求释放运输连接。

(12)窗口:窗口指发送本报文段的一方的接受窗口。窗口值告诉对方,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化着。

(13)检验和:和UDP一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部,但应把伪首部第4个字段中的17改为6。

(14)紧急指针:指出本报文段中的紧急数据字节数(紧急数据结束后就是普通数据)。紧急指针仅在URG=1时才有意义。即使窗口为0时也可发送紧急数据。

(15)选项:长度可变,最长可达40字节。最后的填充字段仅仅是为了整个TCP首部长度是4字节的整数倍。

        a. 最大报文段长度MSS(Maximum Segment Size):指每个TCP报文段中的数据字段的最大长度,而非整个TCP报文段的最大长度。因为报文段长度过大或过小都会降低网络的利用率,所以规定MSS是很有必要的。若主机未填写这一项,则MSS的默认值是536字节(576字节的IP数据报总长度减去TCP和IP的固定首部)。因此,所有互联网上的主机都应能接受的报文段长度是536+20(固定首部长度)=556字节。

        b. 窗口扩大:占3字节,其中一个字节表示移位值S。新的窗口值等于TCP首部中的窗口位数从16增大到16+S。移位值允许使用的最大值是14,相当于窗口最大值增大到2^(16+14)-1。

        c. 时间戳:占10字节,其中最主要的字段是时间戳值字段(4字节)和时间戳回送回答字段(4字节)。主要用来计算往返时间RTT和处理TCP序号超过2^32的情况,即防止序号绕回PAWS(Protect Against Wrapped Sequence numbers)。

        d. 选择确认

3.4 TCP可靠传输的实现

TCP的通信是全双工通道,通信中的每一方都在发送和接受报文段。因此,每一方都有自己的发送窗口和接收窗口。为了讲述可靠传输原理的方便,我们假定数据传输只在一个方向进行,即A发送数据,B给出确认。

3.4.1 以字节为单位的滑动窗口

TCP的滑动窗口是以字节为单位的。

3.4.1.1 A的发送窗口

(1)构造发送窗口

假定A收到了B发来的确认报文段,其中窗口是20字节,确认号是31(B期望收到的下一个字节)。根据这两个数据,A就构造出了自己的发送窗口。

(2)发送窗口的工作机制

在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。

(3)发送窗口的组成

发送窗口里面的序号表示允许发送的序号。显然,窗口越大,发送方就可以在收到对方确认之前连续发送更多的数据,因而可能获得更高的传输效率。发送窗口的大小和B的接收窗口数值以及网络拥塞程度有关,在此不考虑网络拥塞的影响。

发送窗口后沿的后面部分表示已发送且已收到了确认,无需保留这部分数据。发送窗口前沿的前面部分表示不允许发送,因为接收方没有临时存放这部分数据的缓存空间。

发送窗口后沿可能不动(没有收到新的确认)或前移(收到了新的确认),而不可能后移(无法撤销已收到的确认)。发送窗口前沿可能前移,可能不动(未收到确认且窗口大小不变,亦或收到了确认但窗口缩小),也可能后移(未收到确认或收到确认较少,且窗口缩小)。TCP标准强烈不赞成前沿后移,因为很可能发送方在收到这个通知之前已经发送了窗口中的许多数据,但现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误。

(4)发送窗口的状态表示

要描述一个发送窗口的状态需要三个指针:P1,P2和P3。指针都指向字节的序号。A的发送窗口中三个指针指向的几个部分的意义如上图所示。

3.4.1.2 B的接收窗口

在图中,B收到了序号为32和33的数据,但序号为31的数据没有收到(也许丢失了,也许滞留在网络某处)。请注意,B只能对按序收到的数据中的最高序号给出确认,因此B发送的确认报文段中的确认号依然是31(即期望收到的序号)。

3.4.1.3 窗口的滑动过程

现假定B收到了序号为31的数据,把序号为31~33的数据交付主机,删除这些数据。接着把接收窗口向前移动3个序号(如上图所示),同时给A发送确认,其中窗口值仍为20,但确认号是34.这表明B已经收到了到序号33为止的数据。我们注意到,B还收到了序号为37,38,和40的数据,但这些数据都没有按序到达,只能先暂存在接收窗口中。

A收到B的确认后,就可以把发送窗口向前滑动3个序号但指针P2不动。可以看出,现在A的可用窗口增大了些,可发送的序号范围是42~53。

A在继续发送完序号42~53的数据后,指针P2向前移动和P3重合。发送窗口内的序号都已用完,但还没有再收到确认(如上图所示)。由于A的发送窗口已满,可用窗口减小到0,因此必须停止发送。

请注意,存在下面这种可能性,就是发送窗口内所有的数据都已正确到达B,B也早已发出了确认。但不幸的是,所有这些确认都滞留在网络中。再没有收到B的确认时,为了保证可靠传输,A只能认为B还没有收到这些数据。于是,A在经过一段时间后(由超时计时器控制)就重传这部分数据,重新设置超时计时器,直到收到B的确认为止。如果A按序收到落在发送窗口内的确认号,那么A就可以使发送窗口继续向前滑动,并发送新的数据。

3.4.1.4 窗口和缓存的关系

前提:

发送方的应用进程把字节流写入TCP的发送缓存,接收方的应用进程从TCP的接收缓存中读取字节流。

缓存空间和序号空间都是有限的,并且都是循环使用的,所以实际上是圆环状,并不是长条状。

发送方:

发送窗口通常只是发送缓存的一部分。已被确认的数据应当从发送缓存中删除,因此发送缓存和发送窗口的后沿是重合的。发送应用程序最后写入发送缓存的字节减去最后被确认的字节,就是还保留在发送缓存中的被写入的字节数。发送应用程序必须控制写入缓存的速率,不能太快,否则发送缓存就会没有存放数据的空间。

接收方:

如果收到的分组被检测出有差错,则要丢弃。如果接收应用程序来不及读取收到的数据,接收缓存最终会被填满,使接收窗口减小到0。反之,如果接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存的大小。

3.4.1.5 三个重点

(1)虽然A的发送窗口是根据B的接收窗口设置的,但在同一时刻,A的发送窗口并不总是和B的接收窗口一样大,因为通过网络传送窗口值需要经历一定时间之后,另外A还可能根据网络当时的拥塞情况适当减小自己的发送窗口数值。

(2)TCP通常把不按序到达的数据先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。因为如果接收方把不按序到达的数据一律丢弃,虽然较简单,但发送方会重传较多数据,对网络资源的利用不利。

(3)TCP要求接收方必须有累计确认功能,这样可以减小传输开销。但接收方不应过分推迟发送确认,否则会导致发送方不必要的重传。TCP标准规定,确认推迟的时间不应超过0.5秒。

3.4.2 超时重传时间的选择
3.4.2.1 计算RTO的算法

(1)报文段的往返时间RTT(Round Trip Time)

收到确认时间-报文段发出的时间

(2)加权平均往返时间RTTS(Round Trip Time Smoothed)

RTTS相较于RTT更加平滑。

计算方法:

每当第一次测量到RTT样本时,RTTS值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本,就按下式重新计算一次RTTS:

在上式中,0<=α<=1,RFC6298推荐α值为1/8。

(3)RTTD

RTTD是RTT的偏差的加权平均值。

计算方法:

当第一次测量时,RTTD值取为测量到的RTT样本值的一半。在以后的测量中,则使用下式计算加权平均的RTTD:

这里的β小于1,推荐值是1/4。

(4)超时重传时间RTO(Retransmission Time-Out)

RTO由超时计时器设置。

计算方法:

3.4.2.2 往返时间的测量

问题:

如上图所示,发送出一个报文段,设定的重传时间到了,但还没有收到确认,于是重传报文段。经过一段时间后,收到了确认报文段。如何判定此确认报文段是对先发送的报文段的确认,还是对后来重传报文段的确认?

若收到的是对重传报文段的确认,却被源主机当成是对原报文段的确认,则这样计算出的RTTS和RTO就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,则按此方法得出的RTO就越来越长。反之,RTO则越来越短。

解决方法:

Karn算法,在计算RTTS时,只要报文段重传了,就不采用其RTT样本。但在RTT一直很大的情况下,发送方一直重传且RTT不被采用,造成RTO无法更新,算法陷入死循环。

修正的Karn算法,即报文段每重传一次,就把RTO增大2倍。当不再发生报文段的重传时,才按公式计算。

3.4.3 选择确认SACK

功能:针对数据不连续的报文段,只传送缺少的数据而不重传已经正确到达接收方的数据。

原理:接收方将已收到的前后不连续的字块的两个边界填入SACK中,使发送方不再重复发送这些已收到的数据。

格式:首部选项最长为40字节,而指明一个边界需要4字节(因为序号有32位),并且还需要一个字节指明SACK选项,另一个字节指明这个选项占用的字节数,所以在选项中最多只能指明4个字节块的边界信息,共占用34个字节。

注意:SACK文档并未指明发送方应当怎样相应SACK,因此大多数的实现还是重传所有未被确认的数据块。

3.5 TCP的流量控制

流量控制(flow control):让发送方的发送速率不要太快,要让接收方来得及接收。

3.5.1 利用滑动窗口实现流量控制

上图接收窗口初始值为400。

如图所示,接收方的主机B进行了三次流量控制,分别把窗口减小到300,100和0。当rwnd=0时,意味着接收方B不允许发送方A发送数据了。这种使发送方暂停发送的状态将持续到主机B重新发送一个新窗口值为止。

问题:

若在B向A发送了零窗口的报文段后不久,B的接收缓存又有了一些存储空间,于是向A发送了rwnd=400的报文段。然而这个报文段在传送过程中丢失了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。

解决办法:

TCP为每一个连接设有一个持续计时器(persistence timer)。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节数据)。而对方就在确认这个探测报文段时给出现在的窗口值。如果窗口仍是零,那么收到这个报文段的一方就重置持续计时器。

3.5.2 TCP的传输效率

问题一:如何控制TCP发送报文段的时机

解决办法:Nagle算法

若发送应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显减少所用的网络带宽。Nagle算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度(MSS)时,就立即发送一个报文段。这样做,就可以有效地提高网络的吞吐量。

问题二:如何控制TCP发送确认的时机(糊涂窗口综合征 silly window syndrome)

解决办法:

可以让接收方等待一段时间,使得接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的时间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。

上述两种方法可配合使用,使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方

3.6 TCP的拥塞控制

3.6.1 拥塞控制的基本概念

拥塞(congestion):在计算机网络中的链路容量(即带宽)、交换节点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。

拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。

拥塞控制与流量控制的区别:拥塞控制是让网络能够承受现有的网络负荷,是一个全局性的过程,涉及所有的主机、路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是指点对点的通信量的控制,是个端到端的问题(接收端控制发送端),它所要做的是抑制发送端发送数据的速率,以便接收端来得及接收。当然,拥塞控制和流量控制也有相似的地方,即它们都通过控制发送方发送数据的速率来达到控制效果。

3.6.2 拥塞控制的具体方法

TCP进行拥塞控制的算法有四种,即慢开始(slow-start)、拥塞避免(congestion avoidance)、快重传(fast retransmit)和快恢复(fast recovery)。

发送方维护接收窗口rwnd和拥塞窗口cwnd。

(1)慢开始

方法:

慢开始算法的启用时机有两个,一个是网络传输刚开始时,另一个是网络发生拥塞时。发送方在超时重传计时器启动时,就判断网络出现了拥塞,此时置ssthresh=cwnd/2,cwnd=初始拥塞窗口,并开始慢开始算法。

设N是原先未被确认的、但现在被刚收到的确认报文段所确认的字节数。SMSS为发送方的最大报文段SMSS(Sender Maximum Segment Size)。

意义:

由小到大逐渐增大注入到网络中的数据字节,避免在不清楚网络当前负荷情况的前提下,把大量数据字节注入到网络中。 

 (2)拥塞避免

方法:

若cwnd大于慢开始门限ssthresh,则停止使用慢开始算法而改用拥塞避免算法。

每经过一个往返时间RTT,cwnd就加一。

意义:

由于拥塞窗口在慢开始阶段呈指数级别增长,很容易增长过大引起网络拥塞,故使用拥塞避免算法让其缓慢增大。

(3)快重传和快恢复

方法:

接收方不要捎带确认,而要立即确认,即使收到了失序报文段也要立即发出对已收到的报文段的重复确认。发送方在连续接收到3个重复确认时,立即重传。

发送方在3-ACK时,置ssthresh=cwnd/2,cwnd=ssthresh,并开始执行拥塞避免算法。

意义:

3-ACK情况产生的具体原因见下图

 可见3-ACK情况产生的原因并非网络拥塞,而是单个报文的丢失。

所以,此时采用快重传和快恢复算法避免了发送方误以为网络发生了拥塞,而错误地启动慢开始算法并将cwnd置为1。

采用快重传算法可以使发送方今早知道个别报文的丢失并立即重传,避免了超时重传的等待时间,提高了网络的吞吐量;采用快恢复算法(缩小cwnd方式)的理由未知。

3.6.3 主动队列管理AQM(Active Queue Management)

全局同步(global synchronization):由于路由器在队列已满时会采用尾部丢弃策略,导致发送方出现超时重传,使得多条TCP连接在同一时间进入到慢开始状态。

全局同步使得全网的通信量突然下降了许多,而在网络恢复正常后,其通信量又突然增大很多。主动队列管理AQM就是针对这一现象而产生的解决办法。

AQM可以有不同的实现方法,其中曾流行多年的就是随机早期检测RED(Random Early Detection)。但多年的实践证明,RED的使用效果并不太理想。现在已经有几种不同的算法来替代RED,但都还在实验阶段。

3.7 TCP的运输连接管理

TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,运输连接就有三个阶段,即:连接建立、数据传送和连接释放。运输连接的管理就是使运输连接的建立和释放都能正常地进行。

在TCP连接建立过程中要解决以下三个问题:

(1)要使每一方能够确知对方的存在。

(2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。

(3)能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client),而被动等待连接建立的应用进程叫做服务器(server)。

3.7.1 TCP的连接建立

下图画出了三报文握手建立TCP连接的过程。

 在本例中,A主动打开连接,而B被动打开连接。二者在一开始都要先创建传输控制块TCB。第一个报文段为SYN报文段,根据TCP规定,不能携带数据但要消耗掉一个序号。第二个报文段同样不能携带数据但要消耗掉一个序号。第三个报文段为ACK报文段,根据TCP规定,可以携带数据,但如果不携带数据则不消耗序号。

第二个报文段可以分成两个报文段,一个为SYN报文段,另一个为ACK报文段,这样就变成了四报文握手。

A发送第三个报文段的原因:防止已失效的连接请求报文段在连接释放后又传送到了B,导致B发出确认并进入SYN-RCVD阶段,但A并未发出建立连接的请求,因此忽略B的确认,而B却以为连接已经建立,一直等待A发来数据。

3.7.2 TCP的连接释放

下图画出了四报文握手释放TCP连接的过程。

 第一个和第三个报文段为FIN报文段,根据TCP规定,即使不携带数据也要消耗一个序号。

A和B在发送完释放连接报文段之后都要停止发送数据。当B收到连接释放报文段并发送确认后,TCP服务器进程这时通知高层应用程序,因而从A到B这个方向的连接就释放了,而从B到A的连接并没有,此时TCP连接处于半关闭(half-close)状态。当A收到连接释放报文段并发送确认后,会进入TIME-WAIT状态,此时TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL(Maximum Segment Lifetime,最长报文段寿命)后,A才能进入CLOSED状态。

从数据传输的角度来看,A可以给B发送数据的时间有ESTABLISHED阶段,而B在ESTABLISHED和CLOSE-WAIT阶段都可以给A发送数据。

A在TIME-WAIT状态必须等待2MSL的原因:

(1)保证A发送的最后一个ACK报文段能够到达B。若此报文丢失,则B会超时重传FIN+ACK报文段,接着A重传一次确认,并重新启动计时器。

(2)防止上一节提到的“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL,就可以使笨连接持续时间内所产生的所有报文段都从网络中消失,从而使新的连接中不会出现旧的连接的报文。

除时间等待计时器外,TCP还设有保活计时器(keepalive timer)。若服务器在保活计时器所设时间范围内没有收到客户的数据,接着进行探测后仍无客户响应,那么服务器就认为客户端出了故障,从而关闭这个连接。

3.7.3 TCP的有限状态机

下图给出了TCP的有限状态机,其中粗线表示对客户进程的正常变迁,粗虚线表示对服务器进程的正常变迁,细线表示异常变迁。

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值