【问题标题】:write always returns EAGAIN for connected nonblock socket after a whilewrite 总是在一段时间后为连接的非阻塞套接字返回 EAGAIN
【发布时间】:2014-07-04 12:11:17
【问题描述】:

我正在 ubuntu linux 机器上用 c 语言编写客户端服务器套接字程序。 服务器端需要处理许多连接,并且服务器和客户端都有一个本地套接字,可以在对其进行一些操作后将接收到的数据发送到本地进程,并且发送和接收的数据数量巨大。 (数据量不是很大,最大1500) 这是图表:
[客户端本地进程] 数据 客户端 服务器 数据 [服务器本地进程]

所以所有的套接字(client_local_socket、client_remote_socket、server_remote_socket、server_local_socket)都需要是非阻塞的。

当我在局域网中的两台计算机上运行客户端和服务器时,它可以正常工作,但是当将服务器程序移动到互联网中的 linux 服务器时(客户端连接到 nat 后面的服务器)客户端开始与服务器成功通信(客户端和服务器都有一些 EAGAIN 错误,但在下一次尝试后恢复它,因为我知道它对于非阻塞非常正常)但过了一段时间(超过 1000 个发送和接收数据包),client_remote_socket 无法写入错误代码 EAGAIN并且在接下来的尝试中无法恢复它,在那之后,它总是得到这个该死的 EAGAIN 写作。 BTW client_remote_socket 读取没有问题,并且总是从服务器获取数据包。服务器完全没有问题,client_local_socket 读写都很好。

我已使用此代码使套接字变为非阻塞:

int flags;
if ((flags = fcntl(client_remote_socket, F_GETFL, 0)) < 0)
    flags = 0;
flags = flags | O_NONBLOCK;
fcntl(client_remote_socket, F_SETFL, flags);

我也试过了:

fcntl(client_remote_socket, F_SETFL, O_NONBLOCK);

但结果是一样的。

我使用的唯一 setsockopt 是服务器端的 SO_REUSEADDR,客户端没有 setsockopt。

值得一提的是,我总是检查 write 返回的值,当它为

【问题讨论】:

  • 我看你别无选择,只能贴出相关代码。
  • 不允许套接字使用所有内存,套接字缓冲区有限制,通常最多为几 MB。获取 EAGAIN 是 100% 正常的,这通常意味着网络无法处理更多流量,或者接收应用程序接收速度不够快。
  • 让我觉得很奇怪的是,在第一段中,您说“服务器端需要处理许多连接”,而在最后一段中,“我还使用了 select 系统调用”,显然是一种调试机制,而不是作为处理许多连接的必要部分。如果您只是在send 的循环中获得大量的 EGAIN,这不足为奇。
  • 谢谢你们帮助我。@Duck 现在,我是唯一连接到服务器的客户端,实时日志显示我可怜的服务器正在等待连接,这是客户端不能发送数据包。得到一堆 EGAIN 对我来说也不足为奇,但问题是,它在几分钟内从不发送任何数据包。我什至已经测试了 15 分钟,但仍然只是 EGAIN :|我使用的选择只返回 0。
  • @nos 我的套接字缓冲区只有 2000 字节,它总是使用最多 1600 或 1700。所以我没有违反 linux 写入缓冲区的大小。网络监控显示没有超出带宽。数据包很小。

标签: c linux sockets nonblocking


【解决方案1】:

上周我遇到了同样的问题,经过研究我发现这是因为对等方的缓冲区已满。我测试了这个案例。

当远程缓冲区已满时,它会告诉您的本地堆栈停止发送。当数据从远程缓冲区中清除(被远程应用程序读取)时,远程系统将通知本地系统发送更多数据。

这是布莱恩·怀特的回答 https://stackoverflow.com/a/14244450/3728361

【讨论】:

  • 谢谢你的回答。您对 tcp 中的这种行为完全正确,我相信答案会对某人有所帮助。但在我的情况下,由于 tcp 黑洞,这是互联网路径中 isp 的路由器故障。我已经发布了一个答案,但声音并没有填满 stackoverflow 的规则并已被删除
猜你喜欢
  • 2010-10-18
  • 1970-01-01
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多