zoukankan      html  css  js  c++  java
  • 【TCP/IP详解 卷一:协议】第二十二章 TCP的坚持定时器

    这两章来到了TCP的定时器部分,在 TCP的超时与重传 和 TCP的三握四挥 我们介绍了 TCP的重传定时器 和 TCP的2MSL定时器。
    本随笔介绍 防止返回ACK丢失的死锁情况 的 坚持定时器 和 检测连接的 保活定时器。
    在坚持定时器的内容里,介绍了 糊涂窗口综合症,以及解决的措施。

    TCP的坚持定时器

    坚持定时器

    我们在前面已经看到,当返回的ACK指明的窗口为0时,会有效地阻止发送方传送数据。
    但是,一个问题仍然存在:ACK的传输 并不可靠。也就是说,TCP不对ACK报文段进行确认,TCP只确认 那些包含有数据的 窗口更新。

    如果一个确认丢失了,那么双方很有可能因为等待对方而使连接终止:接收方等待接收数据(因为已经向发送方发送了一个 非0的通告窗口),发送方等待窗口更新。这就是死锁现象。
    为了防止这种死锁现象的产生,发送方使用一个 坚持定时器 来 周期性地向接收方查询,以便发现窗口是否增大。
    这些查询,称为 窗口探查。

    当接收到 窗口为0 的通知窗口后,发送方停止发送数据,引起客户设置坚持定时器。如果在定时器时间到的时候,客户还没有接收到一个窗口更新,它就探查这个空的窗口以决定窗口更新是否丢失。
    计算坚持定时器的时候,使用了普通的指数退避。
    坚持状态 与前面介绍的 重传超时 之间一个不同的特点就是:TCP 从不放弃 窗口探查,这些探查每隔60s发送一次。这个过程 将持续到 窗口被打开(通告窗口不为0) 或者 应用程序使用的连接 被结束。

    糊涂窗口综合症

    基于窗口的 流量控制方案 会导致一种称为 糊涂窗口综合症 的情况。即 发送 少量 数据,而不是满长度的报文段,通过连接进行交换。
    这个现象可以发生在 接收端 和 发送端:接收方通告一个很小的窗口(而不是一直等到有较大的窗口时,即缓存较为宽松的时候 发送);发送方发送很少的数据(而不是等待其他的数据一起发送)

    解决方法:
    (1)接收方不通告小窗口。当窗口增大到 缓存的一半时,或者增加了一个报文段的长度(即字节增加了一个 MSS),才允许通告非0的通告窗口。
    (2)发送方在出现 以下状况之一 时才发送数据:

    • a) 可以发送一个 满长度 的数据报
    • b) 可以发送 大于等于 1/2通告窗口 的报文段
    • c) 能够发送手头中的所有数据,并且不希望接收ACK(就是说,我们还没有 未确认的数据) 或者 连接禁止了Nagle算法(也就是说 不能使用Nagle算法)

    条件b 主要用来对付那些 总是通告小窗口的较老的,原始的主机,这要求发送方始终监视另外一方的通告窗口,这是一种发送方 猜测 对方接受缓存大小 的企图。
    Nagle算法阻止我们发送小的分组,那么多小算小呢?从条件a可以看出来: 字节数小于报文段的大小 即为小。

    一个例子

    教材P249提到了一个例子,在 接收方返回的 第13个报文段 上 通告的窗口大小 为509,这似乎与我们前面看到的防止发送小分组相违背···

    我这里提供更多的细节:
    之前的报文段:报文段11(接收方->发送方):win 1533,报文段12(发送方->接收方):1024bit,报文段13(接收方->发送方):win 509.
    之所以发生这种情况,是因为我们之前提到的 滑动窗口机制:窗口右沿 不允许向左边移动。

    在报文段11的时候,窗口的大小是 1533,假定 左边沿 所在的地方 为 A字节,右边沿 所在的地方 为 B字节,区别 已发送但未确认的数据 和 未发送的数据 所在的界限为 C字节

    A -> B = 1533, C -> B = 509, A -> C = 1024

    那么发送方发送了1024字节,左边沿往右移动,移动到了C处。
    此时,如果接收方通告窗口为 win0,那么意味着 B要向C靠拢,不符合 滑动窗口机制。
    因此,报文段13 为 win509.

    问题

    • 为什么要有 TCP坚持定时器?
      答:避免通告窗口的丢失造成的 死锁现象。
    • TCP为什么要避免糊涂窗口综合症?
      答:避免通告小的窗口大小,或者发送小的报文段。与之前我们提到的Nagle算法类似:避免造成 广域网(etc,网络比较缓慢) 的网络拥塞。

    2016/8/18

  • 相关阅读:
    Linux (Ubuntu)安装ssh
    Linux (Ubuntu)提示ifconfig:找不到命令
    Docker介绍
    微服务用到的技术
    移动端BI的设计
    Cobbler Web管理(二)
    基于CentOS7环境下的Cobbler部署介绍(一)
    使用google-perftools优化nginx内存管理提升性能
    解决 nginx 配置TLS1.2无效,总是TLS1.0的问题
    在nginx中将爬虫过来的请求转到指定的后端服务
  • 原文地址:https://www.cnblogs.com/qq952693358/p/5784883.html
Copyright © 2011-2022 走看看