第19章 TCP的交互数据流

所属:TCP/IP详解 卷1:协议 来源:TCP/IP详解 卷1:协议

本章介绍TCP的交互数据流,包括交互式输入、经受时延的确认、Nagle算法等。


19.1 引言

交互数据流

交互数据流(Interactive Data Flow):

  • 交互式应用的数据
  • 比如远程登录(Telnet, Rlogin)
  • 每次发一点点数据
  • 一个字符一个字符地发
  • 小包很多

交互式应用产生很多小包。


交互数据流的特点

交互数据流的特点:

  1. 数据量小

    • 每次一个字符或几个字符
    • 小包很多
  2. 实时性要求高

    • 输入要马上有反应
    • 延迟要小
  3. 双向交互

    • 客户端发输入
    • 服务器回显
    • 一来一回
  4. 小包问题

    • 40字节首部 + 1字节数据
    • 效率很低
    • 网络负担重

交互式应用的特点是小包多。


本章讨论的内容

本章讨论的内容:

  • 交互式输入
  • 经受时延的确认
  • Nagle算法
  • 窗口大小通告
  • 糊涂窗口综合征

本章介绍交互数据流的处理。


19.2 交互式输入

远程登录的例子

远程登录的例子:

  • 用户敲一个键
  • 客户端发一个字符给服务器
  • 服务器收到,回显这个字符
  • 客户端收到回显,显示给用户

数据流:

客户端 → 服务器:1字节数据(字符)
服务器 → 客户端:1字节数据(回显) + ACK
客户端 → 服务器:ACK

问题:

  • 一个字符产生三个包
  • 40字节首部 + 1字节数据
  • 效率极低
  • 网络负担重

一个字符产生很多包。


小包的问题

小包的问题:

  1. 效率低

    • 首部开销大
    • 40字节首部,1字节数据
    • 利用率只有2.5%
  2. 网络负担重

    • 包的数量多
    • 路由器处理每个包
    • 负担重
  3. 拥塞

    • 太多小包
    • 容易拥塞

小包效率很低。


19.3 经受时延的确认

什么是经受时延的确认

经受时延的确认(Delayed ACK):

  • 收到数据不马上确认
  • 等一会儿
  • 看看有没有数据要发
  • 有数据就捎带确认
  • 没有就单独发确认

目的:

  • 减少包的数量
  • 用一个包既发数据又发确认
  • 提高效率

延迟确认,等捎带。


时延的时间

时延的时间:

  • 通常是200ms
  • 最多等200ms
  • 等不到数据就单独发ACK
  • 不能等太久,不然影响RTT测量

为什么是200ms:

  • 平衡效率和延迟
  • 等太久影响性能
  • 等太短没效果

最多等200ms。


什么时候不延迟

什么时候不延迟,马上发ACK:

  1. 收到乱序的段

    • 要马上发ACK
    • 告诉发送方缺了什么
    • 让发送方快点重传
  2. 收到FIN

    • 要马上ACK
    • 不能等
  3. 缓冲区满了一半以上

    • 要马上通告窗口
    • 让发送方知道

有些情况要马上发ACK。


效果

延迟确认的效果:

  • 减少ACK的数量
  • 很多ACK被捎带了
  • 减少网络流量
  • 提高效率

代价:

  • 确认稍微晚一点
  • 但通常不影响
  • 因为有数据捎带

延迟确认减少包数量。


19.4 Nagle算法

什么是Nagle算法

Nagle算法:

  • 解决小包太多的问题
  • 要求:
    • 一个连接上最多只能有一个未被确认的小包
    • 在收到ACK之前,不能发更多小包
    • 收集小包,等ACK来了一起发
    • 或者攒够一个大包再发

目的:

  • 减少小包数量
  • 提高网络利用率
  • 防止拥塞

Nagle算法减少小包。


Nagle算法的规则

Nagle算法的规则:

  1. 如果窗口够大,数据够多

    • 发一个最大段
    • 正常发
  2. 如果有未确认的数据

    • 把小数据放缓冲区
    • 攒着
    • 等ACK来了再发
    • 或者攒够一个MSS再发
  3. 如果没有未确认的数据

    • 有数据就马上发
    • 不管大小

最多一个未确认的小包。


例子

例子:用户快速敲键盘

没有Nagle:

  • 敲一个发一个
  • 每个字符一个包
  • 很多小包

有Nagle:

  • 敲第一个字符,发出去
  • 等ACK的时候,又敲了几个字符
  • 攒起来
  • ACK来了,把攒的一起发
  • 包的数量大大减少

Nagle算法把小包攒起来发。


Nagle算法的优缺点

优点:

  • 减少小包数量
  • 提高网络利用率
  • 防止拥塞
  • 简单有效

缺点:

  • 增加延迟
  • 交互式应用可能感觉慢
  • 比如游戏、实时应用

关闭Nagle:

  • 可以用TCP_NODELAY选项关闭
  • 需要低延迟的应用可以关
  • 但要注意不要造成拥塞

Nagle算法有好有坏。


19.5 窗口大小通告

窗口更新

窗口更新(Window Update):

  • 接收方应用读取了数据
  • 缓冲区有空间了
  • 发送窗口更新
  • 告诉发送方窗口变大了

什么时候发窗口更新:

  • 应用读取数据后
  • 窗口增加了一定量
  • 通告发送方

窗口更新通告窗口大小。


窗口通告的时机

窗口通告的时机:

  • 有数据要发的时候,捎带
  • 没有数据的时候,单独发
  • 窗口变化大的时候发
  • 小变化不发,减少包

为什么小变化不发:

  • 免得窗口更新包太多
  • 等变化大了再发
  • 减少包数量

窗口大变化才通告。


19.6 糊涂窗口综合征

什么是糊涂窗口综合征

糊涂窗口综合征(Silly Window Syndrome, SWS):

  • 接收方窗口很小了
  • 发送方也发很小的包
  • 窗口一点点增加
  • 一点点发
  • 全是小包
  • 效率极低

为什么叫糊涂:

  • 窗口小得可笑
  • 发的数据还没有首部大
  • 很糊涂

糊涂窗口综合征就是全是小包。


产生的原因

产生的原因:

  1. 接收方

    • 应用一次读一点点
    • 窗口一点点增加
    • 每次增加就通告
    • 发送方就发一点点
  2. 发送方

    • 应用一次发一点点
    • 发送方有数据就发
    • 不管大小
    • 全是小包

双方都可能导致。


解决方法

解决方法:

接收方的解决:

  • 不要窗口增加一点就通告
  • 等窗口增加到一定程度再通告
    • 至少一个MSS
    • 或者缓冲区的一半
  • 避免小窗口

发送方的解决:

  • 不要有一点数据就发
  • 等数据够多了再发
    • 至少一个MSS
    • 或者等ACK
  • Nagle算法就是干这个的

双方都要避免。


接收方的避免

接收方避免SWS:

  • 窗口小的时候不通告
  • 等窗口够大了再通告
  • 至少一个MSS
  • 或者缓冲区的一半

为什么:

  • 免得发送方发小包
  • 窗口大了,发送方才能发大包
  • 效率才高

接收方等窗口够大了再通告。


发送方的避免

发送方避免SWS:

  • Nagle算法
  • 不要有一点数据就发
  • 攒够了再发
  • 或者等ACK

为什么:

  • 减少小包
  • 提高效率
  • 防止拥塞

发送方用Nagle算法避免。


19.7 小结

交互数据流

  1. 特点

    • 数据量小
    • 小包多
    • 实时性要求高
    • 效率低
  2. 问题

    • 首部开销大
    • 网络负担重
    • 容易拥塞

经受时延的确认

  1. 什么是延迟确认

    • 收到数据不马上ACK
    • 等一会儿
    • 看看能不能捎带
  2. 时延时间

    • 通常200ms
    • 最多等200ms
  3. 什么时候不延迟

    • 乱序段
    • 收到FIN
    • 窗口变化大
  4. 效果

    • 减少ACK数量
    • 提高效率

Nagle算法

  1. 什么是Nagle算法

    • 解决小包太多
    • 最多一个未确认的小包
    • 攒小包一起发
  2. 规则

    • 有未确认数据就攒着
    • 等ACK或攒够MSS
    • 没有就马上发
  3. 优缺点

    • 优点:减少小包,提高效率
    • 缺点:增加延迟
  4. 关闭

    • TCP_NODELAY
    • 需要低延迟的应用

窗口大小通告

  1. 窗口更新

    • 应用读了数据
    • 通告窗口变大
  2. 通告时机

    • 捎带最好
    • 变化大才单独发
    • 减少包数量

糊涂窗口综合征

  1. 什么是SWS

    • 窗口很小
    • 全是小包
    • 效率极低
  2. 原因

    • 接收方:窗口一点点增加
    • 发送方:数据一点点发
  3. 解决方法

    • 接收方:等窗口够大再通告
    • 发送方:Nagle算法,攒够再发
  4. 接收方避免

    • 至少一个MSS
    • 或缓冲区一半
  5. 发送方避免

    • Nagle算法
    • 攒够了再发

关键概念

  1. 交互数据流

    • 小包多
    • 效率低
  2. 延迟确认

    • 等捎带
    • 减少ACK
  3. Nagle算法

    • 减少小包
    • 攒着发
  4. 糊涂窗口综合征

    • 小窗口小包
    • 双方都要避免

TCP交互数据流