我一直在研究轮询TCP守护程序一段时间。最近,我读到非阻塞套接字有时会在send()或recv()期间引发EWOULDBLOCK错误。我的理解是,如果recv()抛出EWOULDBLOCK,这(通常)意味着什么也没收到。但是我不清楚的是,在什么情况下send()会抛出EWOULDBLOCK,什么是处理此类事件的适当程序?
如果send()抛出一个EWOULDBLOCK,该守护程序是否应该简单地从该事件继续进行到下一个事件?使用像epoll这样的轮询接口(interface),描述符准备就绪时会触发新事件吗?
最佳答案
当发送缓冲区(通常由OS保留,但是无论如何,在TCP/IP堆栈中的某个位置)已满并且对方尚未确认从缓冲区发送给它的任何位时(因此,堆栈必须保留万一需要重新发送,缓冲区中的所有内容)。
您必须以一种或另一种方式等待,直到对方确实确认了发送给它的某些数据包,从而允许TCP/IP堆栈释放空间以进行更多的“发送”。古典select
和更现代的epoll
(以及在其他操作系统中的kqueue
&c)都提供了执行此类等待的巧妙方法(无论您是在等待阅读某些内容,编写某些内容,还是“两者中的先发生者”)。是的,观看描述符准备就绪(无论是阅读还是写作)是epoll
事件的典型原因!
关于c - 在非阻塞套接字上通过轮询正确处理EWOULDBLOCK,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3673828/