c - 通过轮询非阻塞套接字正确处理 EWOULDBLOCK

标签 c sockets epoll

我已经在轮询 TCP 守护程序上工作了一段时间。最近,我了解到非阻塞套接字有时会在 send() 或 recv() 期间抛出 EWOULDBLOCK 错误。我的理解是,如果 recv() 抛出一个 EWOULDBLOCK,这(通常)意味着没有任何东西可以接收。但我不清楚的是在什么情况下 send() 会抛出 EWOULDBLOCK,以及处理此类事件的正确程序是什么?

如果 send() 抛出一个 EWOULDBLOCK,守护进程是否应该简单地从该事件继续到下一个事件?使用像 epoll 这样的轮询接口(interface),当描述符准备好写入时是否会触发新事件?

最佳答案

what I'm unclear on is under what circumstances send() would throw an EWOULDBLOCK

当发送缓冲区(通常由操作系统保存,但无论如何,位于 TCP/IP 堆栈中的某处)已满且对方尚未确认从缓冲区发送给它的任何位时(因此堆栈必须保留缓冲区中的所有内容,以防需要重新发送)。

what would be proper procedure for handling such an event?

以某种方式,您必须等到对方确实确认发送给它的一些数据包,从而允许 TCP/IP 堆栈释放一些空间以进行更多“发送”。经典的 select 和更现代的 epoll(以及在其他操作系统中,kqueue &c)都提供了执行此类等待的智能方法(无论您是在等待读一些东西,写一些东西,或者“两者中先发生的”)。是的,watched-descriptors 准备就绪(无论是用于读取还是用于写入)是 epoll 事件的典型原因!

关于c - 通过轮询非阻塞套接字正确处理 EWOULDBLOCK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3673828/

相关文章:

c# Socket发送接收网络

c - epoll 立即返回标准输入

更改 c 中的程序,因此它需要一个可选的命令行参数 *infile*

java - 从套接字响应中逐字符读取 Kotlin 中的空字符

c - 结构比较

java - 将十六进制字符串作为字节写入套接字java

c - epoll 事件循环内阻塞操作的解决方案

epoll - 为什么epoll_wait只提供1ms的巨大超时?

c - 如何指示 ld 使用 c 查找其他目录?

c - 为什么 C 不创建我的链表头?