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