我从事轮询 TCP 守护进程工作已经有一段时间了。最近,我读到,非阻塞套接字有时会在
EWOULDBLOCK
或send()
期间抛出recv()
错误。我的理解是,如果 recv()
抛出 EWOULDBLOCK
,这(通常)意味着没有任何内容可以接收。但我不清楚在什么情况下 send()
会抛出 EWOULDBLOCK
,以及处理此类事件的正确程序是什么?
如果
send()
抛出 EWOULDBLOCK
,守护进程是否应该简单地从该事件继续前进,进入下一个事件?使用像epoll
这样的轮询接口,当描述符准备好写入时会触发新事件吗?
我不清楚的是在什么下 在这种情况下 send() 会抛出一个 伊沃德布洛克
当发送缓冲区(通常由操作系统保存,但无论如何,在 TCP/IP 堆栈中的某个位置)已满并且对方尚未确认从缓冲区发送到它的任何位时(因此堆栈必须保留缓冲区中的所有内容,以防需要重新发送)。
正确的程序是什么 处理这样的事件?
以一种或另一种方式,您必须等到对方确实确认发送给它的一些数据包,从而允许 TCP/IP 堆栈释放一些空间以进行更多“发送”。 经典的
select
和更现代的 epoll
(以及在其他操作系统中,kqueue
&c)都提供了执行此类等待的智能方法(无论您是在等待读取某些内容、写入某些内容,还是“两者中的任何一个先发生”) ”)。 是的,观看描述符准备就绪(无论是阅读还是写作)是epoll
事件的典型原因!