我正在使用 tcp 进行大量小型发送,我应该关闭 Nagles 算法吗? (人们也知道这为 TCP_NODELAY)

发布于 2024-10-09 12:27:28 字数 274 浏览 8 评论 0原文

我重新制作了这篇文章,因为我的标题选择很糟糕,对此感到抱歉。我的新帖子可以在这里找到:发送大量数据后,我的 send() 调用导致我的程序完全停止。这怎么可能?

非常感谢大家。问题是客户端实际上是机器人,他们从不从连接中读取数据。 (感觉很傻)

I remade this post because my title choice was horrible, sorry about that. My new post can be found here: After sending a lot, my send() call causes my program to stall completely. How is this possible?

Thank you very much everyone. The problem was that the clients are actually bots and they never read from the connections. (Feels foolish)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谎言月老 2024-10-16 12:27:28

TCP_NODELAY 可能有助于减少从发送方到接收方的小数据包的延迟,但您给出的描述指向不同的方向。我可以想象以下内容:

  • 发送的数据多于接收者实际消耗的数据 - 这最终会溢出发送者的缓冲区(SO_SNDBUF) 并导致服务器进程在 send(2) 系统调用。此时,内核等待另一端确认一些未完成的数据,但接收方并不期望它,因此它不会 recv(2)

可能还有其他解释,但不看代码很难判断。

TCP_NODELAY might help latency of small packets from sender to receiver, but the description you gave points into different direction. I can imagine the following:

  • Sending more data than receivers actually consume - this eventually overflows sender's buffer (SO_SNDBUF) and causes the server process to appear "stuck" in the send(2) system call. At this point the kernel waits for the other end to acknowledge some of the outstanding data, but the receiver does not expect it, so it does not recv(2).

There are probably other explanations, but it's hard to tell without seeing the code.

动听の歌 2024-10-16 12:27:28

如果 send() 在 TCP 套接字上阻塞,则表明发送缓冲区已满,这又表明连接另一端的对等方读取数据的速度不够快。也许该客户端完全卡住了,并且没有足够频繁地调用 recv()

If send() is blocking on a TCP socket, it indicates that the send buffer is full, which in turn indicates that the peer on the other end of the connection isn't reading data fast enough. Maybe that client is completely stuck and not calling recv() often enough.

椵侞 2024-10-16 12:27:28

Nagle 不会导致“消失在内核中”,这就是为什么禁用它对您没有帮助。 Nagle 只会缓冲数据一段时间,但最终会在没有用户提示的情况下发送数据。

还有其他罪魁祸首。


编辑更新的问题。

您必须确保客户端正在接收所有发送的数据,并且快速接收数据。让每个客户端写入日志或其他内容以进行验证。

例如,如果客户端正在等待服务器接受其 23 字节更新,则它可能不会接收数据。这可能会导致服务器的发送缓冲区填满,从而导致性能下降并最终导致死锁。

如果这确实是罪魁祸首,那么解决方案将是一些异步通信,例如 Boost 的 Asio 库。

Nagle's wouldn't cause "disappearing into the kernel", which is why disabling it doesn't help you. Nagle's will just buffer data for a little while, but will eventually send it without any prompting from the user.

There is some other culprit.


Edit for the updated question.

You must make sure that the client is receiving all of the sent data, and that it is receiving it quickly. Have each client write to a log or something to verify.

For example, if a client is waiting for the server to accept its 23-byte update, then it might not be receiving the data. That can cause the server's send buffer to fill-up, which would cause degradation and eventual deadlock.

If this is indeed the culprit, the solution would be some asynchronous communication, like Boost's Asio library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文