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

时间:2010-09-09 04:42:38

标签: c sockets epoll

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

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

1 个答案:

答案 0 :(得分:5)

  

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

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

  

什么是适当的程序   处理这样的事件?

以这种或那种方式,您必须等到对方 确认发送给它的一些数据包,从而允许TCP / IP堆栈释放一些空间以进行更多“发送”。经典的select和更现代的epoll(以及其他操作系统,kqueue& c)都提供了智能的方式来执行这样的等待(无论你是在等待阅读,写点什么,或者“先发生两者中的任何一个”。是的,观看描述符准备就绪(无论是阅读还是写作)都是{em> epoll事件的典型原因!