【问题标题】:How does setting TCP_NODELAY behave when TCP_CORK is set?设置 TCP_CORK 时,设置 TCP_NODELAY 的行为如何?
【发布时间】:2021-01-26 00:55:15
【问题描述】:

根据手册页,TCP_CORK 阻止发送部分,取消设置它会刷新部分。设置 TCP_CORK 并设置 TCP_NODELAY 也会刷新部分数据。听起来很像,到底哪里不同?

在设置了 TCP_CORK 的连接上:

  1. 是否正确,TCP_NODELAY 最多刷新单个部分数据包,然后返回 TCP_CORK 行为? (所以它更像是一个事件,而不是一个永久选项!?)(手册页明确提到 All queued partial frames are sent when the option is cleared again. 怎么会有多个排队的部分帧?不是所有部分都合并到一个数据包中吗?)
  2. 能否在 TCP_CORK 连接上重复设置 TCP_NODELAY 以清除待处理的数据? (还是需要先取消设置?)

man tcp:

   TCP_CORK (since Linux 2.2)
          If set, don't send out partial frames.  All queued partial frames are sent when the option is cleared again.  This is useful for prepending headers before calling sendfile(2), or  for
          throughput  optimization.   As  currently  implemented, there is a 200 millisecond ceiling on the time for which output is corked by TCP_CORK.  If this ceiling is reached, then queued
          data is automatically transmitted.  This option can be combined with TCP_NODELAY only since Linux 2.5.71.  This option should not be used in code intended to be portable.
   TCP_NODELAY
          If set, disable the Nagle algorithm.  This means that segments are always sent as soon as possible, even if there is only a small amount of data.  When not set, data is buffered until
          there  is  a  sufficient  amount  to  send out, thereby avoiding the frequent sending of small packets, which results in poor utilization of the network.  This option is overridden by
          TCP_CORK; however, setting this option forces an explicit flush of pending output, even if TCP_CORK is currently set.

【问题讨论】:

    标签: linux tcp


    【解决方案1】:

    这不是一个真正的答案,但我想我还是要分享我得到的。

    我做了一些测试设置。

    客户:

        optval = 1;
        setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, &optval, sizeof(int));
        write(sockfd, "foo\n", 4);
        setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));
        usleep(70000);
        write(sockfd, "bar\n", 4);
        setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));
        usleep(70000);
        write(sockfd, "hello\n", 6);
        usleep(70000);
        write(sockfd, "world\n", 6);
    

    服务器:

    # netcat -l 8123 | ts -i "%.S"
    17.365721 foo
    00.070271 bar
    00.140462 hello
    00.000216 world
    

    选择的 70 毫秒延迟低于 TCP_CORK 标志的 200 毫秒超时。

    如您所见,TCP_NODELAY 可用于反复刷新数据。 (因此回答了问题 2)

    奖励:查看网络上的数据包时,我们可以看到在设置 TCP_NODELAY 时,在数据包上设置了 PSH 标志。因此,数据也可能在接收端被刷新。 (比较Difference between push and urgent flags in TCP

    【讨论】:

      猜你喜欢
      • 2021-03-26
      • 2011-11-09
      • 1970-01-01
      • 2012-11-21
      • 2012-12-27
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多