5

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

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

4

1 回答 1

5

我不清楚的是在什么情况下 send() 会抛出 EWOULDBLOCK

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

处理此类事件的正确程序是什么?

以一种或另一种方式,您必须等到对方确实确认发送给它的一些数据包,从而允许 TCP/IP 堆栈释放一些空间以进行更多“发送”。经典的select和更现代epoll的(以及在其他操作系统中,kqueue&c)都提供了执行这种等待的智能方法(无论您是在等待读取某些内容、写入某些内容,还是“两者中的任何一个先发生”)。是的,被监视的描述符准备好(无论是阅读还是写作)是事件典型原因epoll

于 2010-09-09T04:49:14.300 回答