gpt4 book ai didi

c - write 总是在一段时间后为连接的非阻塞套接字返回 EAGAIN

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:22:10 24 4
gpt4 key购买 nike

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

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

当我在 LAN 网络中的两台计算机上运行客户端和服务器时,它运行良好,但是当将服务器程序移动到 Internet 中的 Linux 服务器时(客户端连接到 nat 后面的服务器)客户端开始与服务器成功通信(客户端和服务器都遇到一些 EAGAIN 错误,但在下一次尝试后恢复它,据我所知,它对于非阻塞来说非常正常)但过了一段时间(超过 1000 个发送和接收数据包),client_remote_socket 写入失败,错误代码为 EAGAIN并且无法在接下来的尝试中恢复它,在那之后,它总是得到这个该死的 EAGAIN 来写。顺便说一句,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 返回的值,当它 <0 时,我检查 errno 并查看它的 EAGAIN。据我所知,写入返回 EAGAIN,当内核没有可用空间用于写入缓冲区时,内核在具有 4 GB ram 的笔记本电脑中没有内存对我来说没有任何意义。顺便说一句,当我在 LAN 网络中同时运行客户端和服务器时,它会很好地工作。当客户端发生这种情况时,服务器不会显示客户端套接字损坏的任何迹象,这是正确的,因为与此同时,它可以从服务器接收数据。我反复检查代码并尝试多次调试它并没有发现任何错误。我还使用 select 系统调用来检查套接字是否可用于写入,并且在时间到来时它总是返回 0。现在我不知道解决这个问题,任何想法对我来说都会非常感激。谢谢。

最佳答案

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

When the remote buffer is full, it tells your local stack to stop sending. When data is cleared from the remote buffer (by being read by the remote application) then the remote system will inform the local system to send more data.

这是 Brian White 的回答 https://stackoverflow.com/a/14244450/3728361

关于c - write 总是在一段时间后为连接的非阻塞套接字返回 EAGAIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19754275/

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