如何在 POSIX 函数 send() 中关闭 TCP PSH 标志?

Posted

技术标签:

【中文标题】如何在 POSIX 函数 send() 中关闭 TCP PSH 标志?【英文标题】:How to turn off TCP PSH flag in the POSIX function send()? 【发布时间】:2019-08-19 13:59:41 【问题描述】:

我正在使用以太网向步进电机系统发送命令。命令使电机移动,或响应驱动器状态,或配置驱动器等......步进电机系统有时会挂起,或无法执行命令,制造商查看了我提供的所有内容后告诉我关闭 TCP 层的 PSH 标志。

Wireshark 的屏幕截图显示了我的代码对 PSH 标志的使用:

我使用的是在 Ubuntu (16.04) 中运行的 C++11。

我的发送函数如下所示:

int sendStatusCode = send(socket , *&pointerToMessageAsCharArray , sizeOfMessage , 0);

我查看了 the writeup 的函数,我知道最后一个参数(我在 0 处有)是一个标志。我不明白的是我需要插入的值以关闭 PSH 标志而不更改任何其他内容(如果可能的话)。你能帮忙吗?

编辑 消息的大小非常小。例如: const char m_ME[5] = m_HEADER_ONE, m_HEADER_TWO, m_M_HEX, m_E_HEX, m_FOOTER_HEX;

发送时如下所示:

我发送的最大消息是 8 个字符,相当于 8 个字节。

编辑 我实现了这个答案 (How would one disable Nagle's algorithm in Linux?),在我看来 TCP_NODELAY 并没有关闭 PSH 标志。我用来检查的代码:

int noDelayState = 1; // 0 means prefer bandwidth optimization over low latency

int tcpPushOptionOff = setsockopt(m_socketRight
    , IPPROTO_TCP
    , TCP_NODELAY
    ,(char *) &noDelayState
    , sizeof(int));

if (tcpPushOptionOff < 0)  /* do smth */ 

【问题讨论】:

您是否在发送套接字上设置 TCP_NODELAY 选项(通过 setsockopt())?如果是这样,您可以尝试不设置该选项。 Wireshark 输出是否表明您正在向电机系统发送部分命令?如果不是,我看不出PSH 标志如何导致问题 - 如果电机系统收到完整的命令包,PSH 标志似乎无关紧要。在这种情况下,这很有可能只是制造商的指责。哎呀,如果电机系统无法处理不完整的数据包,那无论如何都不是很好。毕竟,TCP 连接是 @AndrewHenle 同意——该建议仅用于测试/信息收集目的。我并没有提议将其作为永久解决方案。 @Mike 哦,这是责备,不管取消设置PSH 标志是否使电机控制器正常运行。电机控制器应该如何处理传入的数据包?坐在上面等另一个? PSH 标志应该是无关紧要的。制造商的回答smells。这纯粹是猜测,但我从您的 Wireshark 转储中猜测控制器无法处理您发送给它的 2-3 个数据包/毫秒,以及“关闭 PSH 标志!”是制造商试图降低数据包速率。 制造商在骂你。无论是设置还是清除,PSH 标志都没有实际效果。之所以把它放在那里,是因为最初的 TCP 设计者设想了一个与我们最终得到的完全不同的编程接口。 TCP_NODELAY 对 PSH 标志没有影响,但是没有人说它有。您应该确保它关闭。 【参考方案1】:

使用标准 linux TCP stack you don't have direct control over this. 是否设置 PSH 标志由发送缓冲区和堆栈中的副本控制。使用嵌入式 LWIP 堆栈之类的东西,您可以获得更多控制权。

但是,尝试将 setsockopt(SO_SNDBUF) 设置为一个非常小的值,看看这是否会产生影响。小于您的数据包大小,即几个字节缓冲区大小设置不起作用,因为操作系统强制执行大于帧的最小大小。

【讨论】:

您不能将其设置为几个字节。平台将强制执行的最小值,在 Linux 中为几 K。 @kert 我真的很惊讶我对这个标志无能为力。感谢您关闭这个问题的大门。

以上是关于如何在 POSIX 函数 send() 中关闭 TCP PSH 标志?的主要内容,如果未能解决你的问题,请参考以下文章

在 subprocess.Popen 中关闭标准输入

如何在 VC++ 项目中关闭 Unicode?

如何在 VC++ 项目中关闭 Unicode?

在flutter中关闭endDrawer后如何运行功能

如何在命令窗口中关闭闪烁的光标?

如何在 plotly & R Language 中关闭特定的图例类型?