设置 TCP_CORK 时,设置 TCP_NODELAY 的行为如何? [英] How does setting TCP_NODELAY behave when TCP_CORK is set?

查看:55
本文介绍了设置 TCP_CORK 时,设置 TCP_NODELAY 的行为如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据联机帮助页,TCP_CORK 阻止发送部分,取消设置它会刷新部分.设置 TCP_CORK 并设置 TCP_NODELAY 也会刷新部分数据.听起来很相似,究竟区别在哪里?

According to the manpage, TCP_CORK prevents sending partials, unsetting it flushes partials. Having TCP_CORK set and setting TCP_NODELAY also flushes partial data. Sounds similar, where exactly lies the difference?

在设置了 TCP_CORK 的连接上:

On a connection that has TCP_CORK set:

  1. TCP_NODELAY 最多刷新一个部分数据包,然后返回到 TCP_CORK 行为是否正确?(所以它更像是一个事件,而不是一个永久选项!?)(手册页明确提到所有排队的部分帧在再次清除该选项时发送. 怎么会有多个排队的部分帧?会吗?不是所有的部分都合并成一个包吗?)
  2. 能否在 TCP_CORK 连接上重复设置 TCP_NODELAY 以清除待处理数据?(还是需要先取消设置?)
  1. Is it correct, that TCP_NODELAY flushes at most a single partial packet and afterwards goes back to the TCP_CORK behaviour? (so it's more of an event, than a permanent option!?) (Man page explicitly mentions All queued partial frames are sent when the option is cleared again. How would there be multiple queued partial frames? Wouldn't all partials be coalesced into one packet?)
  2. Can TCP_NODELAY be set repeatedly on a TCP_CORK connection to flush out the pending data? (or would it need to be unset first?)

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.

推荐答案

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

This is not a real answer, but I thought I share what I got anyways.

我做了一些测试设置.

客户:

    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 毫秒超时.

The 70ms delay was chosen to be lower than the 200ms timeout of the TCP_CORK flag.

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

As you can see, TCP_NODELAY can be used to flush the data repeatedly. (Question number 2 is therefore answered)

奖励:查看线路上的数据包时,我们可以看到设置 TCP_NODELAY 时,数据包上设置了 PSH 标志.因此,数据也可能在接收器端被刷新.(比较TCP 中推送和紧急标志之间的区别)

Bonus: When looking at the packets on the wire, we can see that when setting TCP_NODELAY, the PSH flag is set on the packet. Thus the data is possibly also flushed on the receiver end. (Compare Difference between push and urgent flags in TCP)

这篇关于设置 TCP_CORK 时,设置 TCP_NODELAY 的行为如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆