《TCP/IP详解 卷1》 笔记: TCP的交互数据流

来源:互联网 发布:gis软件开发工程师 编辑:程序博客网 时间:2024/05/16 12:14

引言

    一些有关TCP通信量的研究发现,如果按照分组数量计算,约有一半的TCP报文段包含成块数据(如FTP、HTTP和电子邮件),另一半则包含交互数据(如Telnet和SSH)。如果按字节计算,则成块数据与交互数据的比例约为90%和10%。这是因为成块数据的报文段基本上都是满长度的,而交互数据则小得多。

    很明显,TCP需要同时处理这两类数据,但使用的算法不同。

交互式输入

    书中本节讲述的是在一个Rlogin(已经过时的一种远程登陆协议)连接上键入交互命令时产生的数据流。Rlogin连接上一个按键(一个字符,而不是一行)可能会产生4个报文段:(1)来自客户的交互按键;(2)来自服务器的按键确认;(3)来自服务器的按键回显;(4)来自客户的按键回显确认。


    但是,我们一般可以将报文段2数据字节的确认和报文段3数据字节的回显进行合并。于是,一个按键通常会产生3个小的分组。

经受时延的确认

    我们先从bsdi建立到svr4主机的Rlogin连接,然后敲入“date”命令,最后按下回车键,那么可能会产生如下的数据流:


    我们把从bsdi发送到srv4的7个ACK标记为经受时延的ACK。通常TCP在接收到数据时并不立即发送ACK,而是等待是否有数据要发送。为了限制等待的时间,TCP为每个连接都使用一个定时器。如果定时器溢出之前有数据需要发送,它就将ACK与数据一起发送(有时称这种现象为数据捎带ACK)。否则就只发送ACK。

    绝大多数实现采用的定时器间隔为200ms。上图中标记“*”的时刻就是定时器溢出的时刻,可以看到它们的时间间隔都是200ms的倍数。由于将要确认的数据是随机到达的(在时刻16.4ms,474.3ms,831.1ms等),TCP会在定时器溢出时得到通知,这会是之后1~200ms中的任意一刻。

    如果观察svr4为产生所收到的每个字符的回显所使用的时间,则这些时间分别为16.5、16.3、16.5、16.4和17.3ms。这些时间很短,因此产生回显的时刻很大概率在200ms定时器溢出之前,于是我们就没有观察到经受时延的ACK。
Nagle算法
    在局域网上,交互数据流产生的小分组通常不会引起麻烦,因为局域网一般不会出现拥塞。但在广域网上,这些小分组则会增加拥塞出现的可能。一种简单和好的方法就是采用RFC896中所建议的Nagle算法。
    该算法要求一个TCP连接上最多只能有一个未被确认的小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些小分组,并在确认到来时以一个分组(包含多个小分组的数据)的方式发出去。该算法的优越之处在于它是自适应的:确认到达得越快,数据也就发送得越快。默认情况下,Nagle算法都是启用的。
    下图是使用Nagle算法后,slip到一个广域网内的主机vangogh之间使用Rlogin产生的数据流:

    我们观察到使用Nagle算法后,slip发送的数据长度不再是1字节。比如说报文段5中包含2字节的数据。这是因为在报文段3的确认到达之前,有2字节数据不被允许发送。在确认到达后,这2字节数据才被发送。

关闭Nagle算法

    有时我们也需要关闭Nagle算法。比如终端的功能键(F1键等)通常可以产生多个字符序列。当开启Nagle算法时,TCP很可能会发送序列中的第一个字符,然后缓存其他字符并等待对该字符的确认。但当服务器接收到该字符后,它并不发送确认,而是继续等待接收序列中的其他字符。这就会经常触发服务器的经受时延的确认算法。对交互用户而言,这将产生明显的时延。

    使用TCP套接字TCP_NODELAY选项可以关闭Nagle算法。

阅读全文
0 0
原创粉丝点击