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

laz*_*tor 5 c sockets epoll

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

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

Ale*_*lli 5

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

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

处理此类事件的适当程序是什么?

在这种或那种方式,你必须等待,直到对方承认某些发送给它的数据包,从而使TCP/IP堆栈以释放空间,更多的"发送".经典select和更现代epoll(以及其他操作系统,kqueue&c)都提供了执行此类等待的智能方法(无论您是在等待阅读,写东西,还是"先发生两者中的任何一个").是的,观看描述符准备就绪(无论是阅读还是写作)是事件典型原因epoll!