参考:
https://download.csdn.net/download/qq_31567335/10213200
简介:TCP在高速率的环境下虽然也能正常运行,但是会出现某些限制。本章讨论TCP的一些修改建议,这些建议可以使TCP在高速率环境中获得最大的吞吐量。
令人惊奇的是,这些改进建议可以完全的与现有的TCP实现兼容。
Path MTU Discovery
因为tcp不希望发送的数据包在ip层发生分片,因为分片会1.产生更多的ip,tcp头部花销,降低效率。
所以,找到整个路径最大的MTU可以提高效率。
TCP通过在发送的报文段中设置DF(don‘t fragment)标志位,侦听ICMP “can’t fragment”错误,来动态的调整发送的报文的大小。
因为网络会动态的发生变化,所以RFC推荐每隔10分钟会尝试一个更大的报文大小。
Big Packets Or Small Packets
一般认为,报文段越大越好,因为可以更多的分摊头部所带来的花销。
但是作者举了一个例子,说明因为路由器的工作原理是存储再转发,更小的包可以更快的到达目的地。
感觉这个地方作者有点偷换概念了,报文段越大,头部花销越小,应该表示的是更大的吞吐量,和哪个速度更快根本是两个不同的概念。
Long Fat Pipes
之前有讨论过带宽时延积的概念:
带宽时延积=带宽*RTT
带宽时延积特别大的网络称之为长肥管道,TCP在长肥管道上会遇到一系列的问题:
1.为了保持最大的吞吐量,TCP的通告窗口最少得跟带宽时延积一样,但是由于窗口大小只有16位,会出现不够用的情况。窗口扩大选项技术被用来解决这个问题。
2.在LFN(long fat networks)中,丢包会急剧的减小吞吐量。虽然使用了快速重传和快速恢复等算法,但是如果连续丢包,还是会使管道出现没有数据传输的情况,完全恢复要花费多个RTT的时间。
3.现有的TCP实现对于每个连接同一时刻只进行一个RTT测量,这对于LFN来说不够精确。时间戳选项被用来解决这个问题。
4.TCP对每个字节数据使用一个32bit无符号的序号来进行标识。如果在网络中有一个被延迟一段时间的报文段,它所在的连接已被释放,而一个新的连接在这两个主机之间又建立了,怎样才能防止这样的报文段再次出现呢?对于这个问题,PAWS(protection against wrapped sequence numbers)算法利用时间戳选项来解决这个问题。
窗口扩大选项
窗口扩大选项使表示窗口大小的位从16位增加到了32位,但是并不是直接通过改变原有字段的长度实现的,而是在头部选项中增加了一个窗口扩大因子,用一个字节来表示位移数(书上说范围为0-14,不知道为什么没有15)。这样表示窗口最大为6553582^14。
为了使用窗口扩大,两端必须在它们的SYN报文段中发送这个选项。主动建立连接的一方在其SYN中发送这个选项,但是被动建立连接的一方只能够在收到带有这个选项的SYN之后才可以发送这个选项。每个方向上的扩大因子可以不同。如果主动连接的一方发送一个非零的扩大因子,但是没有从另一端收到一个窗口扩大选项,它就将发送和接收的移位记数器置为0。这就允许较新的系统能够与较旧的、不理解新选项的系统进行互操作。(为什么要置为0呢?直接不使用这个选项不更好吗?)
不得不说这是一个很巧妙的设计,使得能够完全向后兼容。
时间戳选项
为了更精确的计算RTT,在TCP头部中增加了一个时间戳选项。
工作原理:发送方在TCP头部中加入这个字段,接收方在发送ack确认的时候将32位的表示时间的值复制到对应位置,加到TCP头部选项中回发。发送方通过ack报文中的时间戳来计算RTT。同窗口扩大选项一样,主动建立连接的一方在TCP头部中声明时间戳选项,只有接收一方回复的报文中也加了这个选项,才允许在以后的报文中使用这个选项。
同样,这样可以保证向后兼容。
但是,由于接收方不会对每个接收到的数据进行ack确认,那么对于确认多个数据的ack,应该选择哪个时间戳进行回复呢?
为了减少任一端所维持的状态数量,对于每个连接只保持一个时间戳的数值。选择何时更新这个数值的算法非常简单,一句话概括就是如果一个ack确认了多个数据,那么时间戳选项的值就用序列号最小的那个报文传送过来的时间戳的值,具体操作如下:
1)接收方维持两个变量:tsrecent,用来保存将要发送的ack报文中应该填写的时间戳的值。lastack,用来保存上一次ack确认所确认的序列号。
2)当一个包含有字节号lastack的报文段到达时,则该报文段中的时间戳被保存在tsrecent中。
3)无论何时发送一个时间戳选项,tsrecent就作为时间戳回显应答字段被发送,而序号字段被保存在lastack中。
这个算法能够处理下面两种情况:
1)如果ACK被接收方迟延,则作为回显值的时间戳值应该对应于最早被确认的报文段。
2)如果一个收到的报文段虽然在窗口范围内但同时又是失序,这就表明前面的报文段已经丢失。当那个丢失的报文段到达时,它的时间戳(而不是失序的报文段的时间戳)将被回显。例如,假定有3个各包含1024字节数据的报文段,按如下顺序接收:包含字节1~1024的报文段1,包含字节2049~4072的报文段3和包含字节1025~2048的报文段2。返回的ACK应该是带有报文段1的时间戳的ACK1025(一个正常的所期望的对数据的ACK)、带有报文段1的时间戳的ACK1025(一个重复的、响应位于窗口内但却是失序的报文段的ACK),然后是带有报文段2的时间戳的ACK3073(不是报文段3中的较后的时间戳)。这与当报文段丢失时的对RTT估计过高具有同样的效果,但这比估计过低要好些。而且,如果最后的ACK含有来自报文段3的时间戳,它可以包括重复的ACK返回和报文段2被重传所需要的时间,或者可以包括发送方的报文段2的重传超时定时器到期的时间。无论在哪一种情况下,回显报文段3的时间戳将引起发送方的RTT计算出现偏差。
T/TCP :A TCP Extension for transactions
略
TCP performances
概括来说,TCP的吞吐量一般可以达到带宽的80%-90%。