将空数据写入非阻塞套接字会导致epoll_wait挂起

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将空数据写入非阻塞套接字会导致epoll_wait挂起相关的知识,希望对你有一定的参考价值。

所以....我很困惑为什么我的基于epoll的tcp服务器随机挂起epoll_wait,然后当我终止SIGINT时向一些连接发送一个空数组。

事实证明,我的软件中有一个随机的错误导致我写了以下内容:

write(server_socket_fd, payload, 0)

虽然这是不正确的,但我当然不希望调用大小为0的写操作会挂起整个事情。

为什么会发生这种行为?如何防止这种情况发生?调用长度参数为零的写只是UB,我应该总是确保大小> 0?

答案

以相反的顺序提出问题,

调用长度参数为零的写只是UB,我应该总是确保大小> 0?

According to POSIX

如果nbyte为零且文件不是常规文件,则结果未指定。

write()的Linux手册页说了同样的话。 “未指定”与标准中的“未定义”不同,但如果您真正关心会发生什么,那么避免未指定的行为也是明智的。

为什么会发生这种行为?如何防止这种情况发生?

防止它的最可靠方法是避免对常规文件以外的任何内容进行零长度写入。可能是您的使用模式中存在特定的某些内容会触发您观察到的不需要的行为,但我们无法评估您未向我们提供的代码,即使我们可以,但行为仍然未指定。我们知道或确定的任何内容可能会在未来的内核或标准库版本中发生变化而不会发出警告。

以上是关于将空数据写入非阻塞套接字会导致epoll_wait挂起的主要内容,如果未能解决你的问题,请参考以下文章

点对点epoll客户端和死锁

什么可能导致非阻塞套接字阻塞“recv”?

如何使用非阻塞套接字正确处理发送/写入?

没有 while(true) 循环的 C# 非阻塞套接字

linux手册翻译——epoll_wait(2)

非阻塞套接字轮询与阻塞套接字