分类: 网络与安全
2013-03-21 08:40:43
10.5.1 TCP流量控制
TCP的流控制方案是采用滑动窗口协议来进行的。而在本章前面已说到,TCP数据段是以字节为单位进行编号的,但一个数据段只有一个TCP头部,所以TCP是以数据段为单位进行传输的,接收端就是通过TCP头部的识别来识别所接收的数据属于哪个数据段的。一个数据段只要没有完全接收,则接收端就不会认为已接收了该数据段,就像我们平时通过QQ等工具传输文件时,只要还有部分没接收完,则你的电脑就不会认为该文件已正确接收,即使已有了文件名,已打不开已接收的部分。
1. 正常情况下的滑动窗口流量控制机制
在本章前面已说到,在通信双方主机上都分别有一个“发送窗口”和一个“接收窗口”。其窗口大小又分“物理窗口大小”和“可用窗口大小”可种。“物理窗口大小”对于一台具体的主机来说,其值是固定的,要视对应主机所配置的缓存大小而定;而“可用窗口大小”是可变的。一端的“发送端口大小”会根据另一端的“接收窗口大小”(会在每个数据段的“窗口大小”字段中设置)调整本端的“发送窗口”大小,也就是说TCP的可用“发送窗口大小”是在不断变化的,而不是固定的,这也说明了TCP每次发送的数据段数(也即数据大小)可能都不一样。而可用“接收窗口”大小也会因向已发送确认的数据段数量和所接收到的不连续序号数据段数量(因为已接收,但不是连续序号的数据段是仍需要缓存在物理“接收窗口”中的)而在不断变化。下面以一个具体的示例来进行“TCP滑动窗口机制”介绍。
如图10-44所示的是一个滑动发送窗口示例,图中的序号为每个数据段的序号,也就是对应数据段的第一个字节序号。现假设每个字段的大小为100个字节(这仅是为了方便介绍,实际上的数据段大小一般都在千个字节以上),假设物理“发送窗口”大小为500个字节(这也是为了方便介绍,实际上的窗口大小远大于这个值)。
图10-44 TCP滑动窗口示例
(1)首先假设现在发送端收到了接收端发来的一个确认数据段,“确认号”为301,“窗口大小”为500,表示可以连续发送5个数据段(起始序号为301)。左边那个虚线“发送窗口”代表的就是后面发送的301、401、501、601、701这五个数据段,此时因为已达到了对方窗口大小值,不能继续发送了,需要停下来等待对端的确认。
(2)如果某一时间收到了一个“确认号”为501的确认数据段(“ACK”字段值为1的数据段,下同),表示接收端已正确接收了301和401这两个数据段,即从“发送窗口”中删除这两个数据段,窗口向前滑动200个字节(也就是301和401这两个数据段的大小),移到了图中细实线“发送窗口”位置。其中501、601和701这三个数据段是原来已发送,但没收到确认的缓存数据段,801和901这两个数据段才是要等待发送的。
假设以上返回的确认数据段中的“窗口大小”为400(这里就起到了流量控制的作用),理论上说发送端可以一次性连续发送4个数据段。但是因为“发送窗口”中缓存了原来已发送的501、601和701这三个数据段(300个字节),再加上物理“发送窗口”大小为500,所以发送当前可用的“发送窗口”大小仅为200个字节,于是此次只能发送100个字节了,即只能先发送后面的801数据段了。
(3)如果此时收到了一个“确认号”为801的确认数据段,同时“窗口大小”字段值又为500了(这里也起到了流量控制的作用),则发送端知道接收端已收到了701号及以前所有的数据段了,于是从“发送窗口”中删除这些缓存的数据段,此时实际上缓存的数据段仅为801号数据段。但原来的901号数据段已在“发送窗口”中,等待发送,所以此时“发送窗口”只需要继续向前移300个字节,也就是三个数据段(此时均是假设数据段大小均为100个字节的情况下),如图10-44所示的粗实线“发送窗口”。继续发送901、1001、1101、1201这四个数据段。
如果在数据传输过程中有一个或多个数据段丢失,则发送端接收不到对这些数据段的确认数据段,这时可以通过上节介绍的超时重传来解决。现在要探讨的一个问题时,如果某个时间,对端发送的数据段显示“窗口大小”字段值为0,这时发送端自然不能再发送数据了,只好等待对方发来一个“窗口大小”字段值不为0的数据段。可是对端发来的这个数据段在传输过程中丢失了,这时对于发送端来说,一直在等待来自接收端“窗口大小”字段值非0的数据段,而接收端又在等待发送端发来新的数据,因为它自己不知道所发送的数据段在途中丢失了(当然这仅适用于C/S模式,对于非C/S模式,也就没有发送端和接收端之分了,双方都可以发送,都可以使用超时重传机制)。
就像你与你朋友约定,在条件满足时他通过快递方式寄一样东西,但你并不知道他具体是什么进修寄,他寄的时候也没告诉你(因为他只相信快递公司)。而恰好这件快递在途中丢失了,结果是你一直在等待你的朋友寄来你所需要的东西(你也不好意催问你的朋友是否寄了),而你的朋友一直在等待你收到的通知(总认为快递一般不会丢东西的)。这样可能等了好久,你的朋友才可能想起这件事,询问你是否收到了这件快递。
为了解决这一问题,TCP中引入了一个称之为“持续计时器”(Persistence Timer)的定时器。它是在TCP连接的一端收到对端的一个“窗口大小”字段值为0的数据段时,就启动该定时器;在这个定时器到期后,收到这个“窗口大小”字段值为0的数据段的一端会向对端发送一个非常小的探测数据段(一般仅携带1个字节的数据),这时对端在收到这个探测数据段后会返回一个确认数据段。如果在确认字段中的“窗口大小”字段值仍为0,则发送端重启上面的“持续定时器”,否则结合确认数据段中的“窗口大小”字段值和当前可用“发送窗口”大小,发送相应字节的数据,解除以上这种双方持续等待的局面。
以上内容摘自刚刚上市,已被纳入全国高校教材系统,并在全国热销、各网店100%高度好评的《深入理解计算机网络》新书。点击这里可以查看京东网、当当网上的真实读者书评: