29TCP的流量控制
我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。因此要控制发送的速率和内容等资源。
解决方式:
流量控制 (flow control) 就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。
利用滑动窗口机制可以很方便地在 TCP 连接上实现流量控制。
可能出现的情况:发生死锁。
比如:
(1)B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。
(2)但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。
(2)如果没有其他措施,这种互相等待的死锁局面将一直延续下去。
解决方法:
为了解决这个问题,TCP 为每一个连接设有一个持续计时器 (persistence timer)。
持续计时器的概念:
(1)TCP 为每一个连接设有一个持续计时器 (persistence timer) 。
(2)只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。
(3)若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。
(4)若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。
(5)若窗口不是零,则死锁的僵局就可以打破了。
如何控制传输效率?
可以用不同的机制来控制 TCP 报文段的发送时机:
第一种机制是 TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。
第二种机制是由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送 (push)操作。
第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去。
发送方糊涂窗口综合症
问题:
发送方 TCP 每次接收到一字节的数据后就发送。
这样,发送一个字节需要形成 41 字节长的 IP 数据报。若接收方确认,并回送这一字节,就需传送总长度为 162 字节共 4 个报文段。效率很低。
解决方法:使用 Nagle 算法。
什么是Nagle 算法?
(1)若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。
(2)当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。
(3)只有在收到对前一个报文段的确认后才继续发送下一个报文段。
(4)当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。
接收方糊涂窗口综合症
问题:
当接收方的 TCP 缓冲区已满,接收方会向发送方发送窗口大小为 0 的报文。
若此时接收方的应用进程以交互方式每次只读取一个字节,于是接收方又发送窗口大小为一个字节的更新报文,发送方应邀发送一个字节的数据(发送的 IP 数据报是 41 字节长),于是接收窗口又满了,如此循环往复。
解决方法:
让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。