TCP(三)

来源:互联网 发布:怛罗斯 知乎 编辑:程序博客网 时间:2024/04/29 10:54

TCP的通信量研究表明,包含成块数据(bulk data)的包的数量和包含交互式数据的包的数量基本持平,前者如FTP,电子邮件等,后者有TelnetRlogin等。这是对包数量的统计,但对字节数量统计显示:通信量的90%是成块数据,而交互式数据只占10%。这是由于成块数据的包都是full sized的,而交互数据往往小得多。有研究发现90%TelnetRlogin包运载不到10个字节的用户数据。

在一个Rlogin连接中,客户端的每次按键都将会产生一个发送给服务器的数据包,即每次发送一个字节。而且远程登录的系统会回送(echo)刚才客户端输入的字符。这样就如下图所示,产生了4TCP段。

然而,通常将第二段和第三段,即对按键的确认和回送结合在一起发送。确认延迟技术将在后面学习。

P264-265详细列出了Rlogin客户端向服务器发送date命令的交互过程。

通常地,TCP并不是在收到数据以后立即发送确认,而是将ACK延迟,看是否有与该ACK同向的数据发送,若有,则将ACK和数据放在同一个TCP段中发送,这称为捎带确认(piggyback ACK)。在大多数实现中,延迟是200毫秒。

Nagle算法

正如我们在上文看到的,在一个Rlogin连接中,每次通常是单个字节从客户端流向服务器。这就产生了41字节的包:20字节IP+20字节TCP+1个字节的数据。由于绝大多数的LAN不存在拥塞(congest),因此在LAN这些小包(叫做tinygrams)通常不成问题,但在WAN,这些小包增加了网络的拥塞。RFC896提出了一个简单而又精致的解决方案,叫做Nagle算法。

该算法主张,一个TCP连接中只要有数据未被确认,其它小包就不能被发送,也就是说,一个TCP连接中只能有一个未被确认的小包。取而代之的做法是,少量的数据被TCP集合在一起,在有确认到达时,它们以单个TCP段的形式发出。此算法的漂亮之处在于它是自同步(self-clocking)的:ACK来得更快,数据也发送得更快。在期望减少tinygrams数目的低速WAN上,将会发送更少的TCP段。

在局域网我们几乎用不到这个算法。

具体看Nagle算法在WAN的应用。本地主机是slip,远程服务器是vangogh.cs.berkeley.edu。下图显示了在客户端快速输入时两端间的数据流

在此图中,我们看不到slipvangogh的延迟的ACK,这是由于在延迟确认计时器到期之前,slip端总是有待发送的数据。

从左到右发送的数据字节数依次是112122313。这是因为客户端将待发数据集合在一起,直到收到上次发送数据的确认才将它们一同发出。使用Nagle算法后,只用9TCP段就发出了16个字节。

14和段15看起来好像与Nagle算法相矛盾,我们需要观察顺序号来了解实际情况。段14是对收到的段12ACK的响应,因为他的确认顺序号是54。但在客户端发出段14之前,收到了服务器发过来的段13。段15包含了对段13的确认,确认号是56。因此即使我们看到客户端向服务器发送了背靠背(back-to-back,不知道NBA背靠背比赛是不是也是这个词)的两个TCP段,客户端还是遵守Nagle算法的。

注意到上图中有一个从服务器到客户端的延迟ACK。因为它不含任何数据,因此我们假定它是一个延迟的确认。服务器当时肯定很忙,在延迟确认计时器到期之前,它无法回送收到的字符。

    现在来观察最后两个段中数据的字节数和数序号。客户端发送3个字节的数据(标号181920),然后服务器确认这3个字节(最后一个段中ACK21),但发回只有一个字节(标号59)。这是由于服务器在正确接受3个字节的数据后立即确认它们,但只有在Rlogin服务器处理之后才回送这3个字节。这表明TCP能够在应用程序读取并处理数据前发送接收到的数据的确认。TCP确认仅仅表明TCP已经正确接收了数据。最后一个段的窗口大小为8189而非8192,这也暗示了服务器进程尚未读取这三个收到的数据。

禁止Nagle算法
    有时,我们需要关闭Nagle算法。经典的例子是X窗口系统服务器:小的消息(鼠标活动)必须无延迟地传送,以给正在进行某些操作的交互用户提供实时反馈。

P270-273Negal算法的实例。