gpt4 book ai didi

c - 在 Linux 中选择慢速套接字

转载 作者:太空狗 更新时间:2023-10-29 11:12:40 24 4
gpt4 key购买 nike

我有一个奇怪的问题,即 select 在 Linux 中的套接字上花费了意外的时间。

  • 服务器一直在接收数据,接收套接字缓冲区大小为65536。
  • 客户端一直在发送数据,发送套接字缓冲区大小为4096。

一般来说,数据传输速度非常快。但是:客户端中的一个 select 来测试写入是否不会阻塞需要很长时间(之前不调用 select 发送数据:0.5s,在实际发送数据之前调用 select 发送相同的数据:5s)。该问题特定于缓冲区大小。如果我将客户端中的发送缓冲区增加到比方说 4*4096,问题就会消失。

现在我想知道为什么选择特定缓冲区大小需要这么长时间。示例代码在这里:http://pastebin.com/PqisLnLU

相同的代码在 Windows 甚至适用于 Linux 的 Windows 子系统上运行而没有这些奇怪的行为。

谢谢!

最佳答案

您正在看到 Nagle's algorithm 的效果,用于以延迟为代价提高 TCP 吞吐量。

写入相对较小,并且在不久的将来写入更多数据时会被延迟,然后可以将这些数据捆绑在一个 IP 数据包中。当您在发送前使用 select 时,您并没有发送更多(因为发送缓冲区仍然是满的),因此在发送数据包(并且缓冲区被清空)之前有一个显着的延迟。相反,当您不使用 select 时,缓冲区已满,因此当您发送 更多内容时,它会立即通过网络堆栈分流。

(我猜你在同一台机器上运行你的客户端和服务器程序,所以它们之间的“网络”连接实际上是环回接口(interface),它具有相当高的 MTU;否则,Nagle 的算法可能不会在这里成为一个问题)。

当您充分增加缓冲区大小时,在填充缓冲区期间的某个时间点会达到合适的 IP 数据包大小,并且数据会立即通过网络推送(并在收到确认后从发送缓冲区中清除)- 所以没有延迟。

尝试禁用 Nagle 算法(在客户端中):

#include <netinet/tcp.h>

...

value = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(int)))
{
printf("\n Error : SetSockOpt TCP_NODELAY Failed \n");
}

您将看到使用 select 的变体与没有 select 操作的变体一样快。

关于c - 在 Linux 中选择慢速套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39270419/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com