我正在使用 tcp 进行大量小型发送,我应该关闭 Nagles 算法吗? (人们也知道这为 TCP_NODELAY)
我重新制作了这篇文章,因为我的标题选择很糟糕,对此感到抱歉。我的新帖子可以在这里找到:发送大量数据后,我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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:SO_SNDBUF
) and causes the server process to appear "stuck" in thesend(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 notrecv(2)
.There are probably other explanations, but it's hard to tell without seeing the code.
如果
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 callingrecv()
often enough.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.