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

问题描述 投票:0回答:1

我从事轮询 TCP 守护进程工作已经有一段时间了。最近,我读到,非阻塞套接字有时会在

EWOULDBLOCK
send()
期间抛出
recv()
错误。我的理解是,如果
recv()
抛出
EWOULDBLOCK
,这(通常)意味着没有任何内容可以接收。但我不清楚在什么情况下
send()
会抛出
EWOULDBLOCK
,以及处理此类事件的正确程序是什么?

如果

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

c sockets posix epoll
1个回答
5
投票

我不清楚的是在什么下 在这种情况下 send() 会抛出一个 伊沃德布洛克

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

正确的程序是什么 处理这样的事件?

以一种或另一种方式,您必须等到对方确实确认发送给它的一些数据包,从而允许 TCP/IP 堆栈释放一些空间以进行更多“发送”。 经典的

select
和更现代的
epoll
(以及在其他操作系统中,
kqueue
&c)都提供了执行此类等待的智能方法(无论您是在等待读取某些内容、写入某些内容,还是“两者中的任何一个先发生”) ”)。 是的,观看描述符准备就绪(无论是阅读还是写作)是epoll事件的典型原因!
    

© www.soinside.com 2019 - 2024. All rights reserved.