为什么 EventMachine 出站数据缓冲区可能会停止发送并永远填满(而其他连接仍然可以发送)

发布于 2025-01-04 06:32:01 字数 308 浏览 1 评论 0原文

我有一个 EventMachine 服务器将 TCP 数据发送到 Mac 客户端(通过 GCDAsyncSocket)。它总是在一段时间内完美地工作,但不可避免的是服务器突然停止逐个连接发送数据。连接仍然保持,服务器仍然接收来自客户端的数据,但不会发生相反的情况。

发生这种情况时,我通过connection#get_outbound_data_size发现连接发送缓冲区无限填满(通过#send_data)并且没有发送到客户端。

发生这种情况是否有具体的(并且希望可以解决的)原因?反应器继续嗡嗡作响,与服务器的其他活动连接继续正常工作(尽管有时也会陷入缓冲区地狱)。

I have an EventMachine server sending TCP data down to a Mac client (via GCDAsyncSocket). It always works flawlessly for a while, but inevitably the server suddenly stops sending data on a connection-by-connection basis. The connection is still maintained, and the server still receives data from the client, but it doesn't go the other way.

When this happens, I've discovered via connection#get_outbound_data_size that the connection send buffer is filling up infinitely (via #send_data) and not being sent to the client.

Are there specific (and hopefully fixable) reasons why this might occur? The reactor keeps humming along, and other active connections to the server continue working fine (though they sometimes fall into buffer hell as well).

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

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

发布评论

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

评论(2

心欲静而疯不止 2025-01-11 06:32:01

我至少看到一个原因:当远程客户端不再从 TCP 连接的一侧读取数据时(使用 recv() 调用或其他方式)。

那么,场景是:客户端的接收TCP缓冲区已满。并且操作系统无法再接受来自其对等方的 TCP 数据包,因为它无法将它们存储在队列中。因此,当您的应用程序继续在套接字上发送 paquet 时,服务器端的发送 TCP 缓冲区也会变满!很快您的服务器将不再能够写入套接字,因为 send() 系统调用将:

  1. 不确定地阻塞。 (等待缓冲区足够空以容纳新的 paquet)
  2. ot 返回 EWOULDBLOCK 错误。 (如果您将套接字配置为非阻塞套接字)

当我在客户端的代码中放置断点时,我通常会在测试环境中遇到这种用例。

I see one reason at least: when the remote client no longer read data from its side of the TCP connection (with a recv() call or whatever).

Then, the scenario is: the receiving TCP buffer on the client side becomes full. And the OS can no longer accepts TCP pacquets from its peer, since it cannot store them queue them. As a consequence, the sending TCP buffer on the server side becomes full too as your application continue to send paquets on the socket! Soon your server is no longer able to write into the socket since the send() system call will :

  1. blocks undefinitively. (waiting for buffer to empty enough for the new paquet)
  2. ot returns with an EWOULDBLOCK error. (if you configured your socket as a non-blocking one)

I usually met that kind of use case in TEST environment when I put a breakpoint in my code on the client side.

银河中√捞星星 2025-01-11 06:32:01

3 月 23 日,补丁已应用于 GCDAsyncSocket,防止读取停止。这个补丁解决了您的问题吗?

There was a patch was applied to GCDAsyncSocket on March 23 that prevents the reads from stopping. Did this patch solve your problem?

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