我正在寻找一种方法来中断阻塞套接字上的accept()
呼叫。使用信号不是一种选择,因为这意味着在库中,我不想弄乱用户信号。使用select()
是另一种选择,由于各种原因,buf 在我的情况下不是很吸引人。
如果可能的话,最好从另一个线程将套接字设置为非阻塞模式(使用 fcntl()
和 O_NONBLOCK
),而套接字在accept()
调用中被阻塞。预期的行为是accept()
调用将以errno
EAGAIN
或EWOULDBLOCK
返回。
真的会这样工作吗?安全吗?便携式?
如果您知道此方法对Windows的适用性(您需要使用WSAIoctl()
和FONBIO
),我也感兴趣。
不知道Windows,但你想要的行为由POSIX保证:
如果侦听队列没有连接请求,并且未在套接字的文件描述符上设置O_NONBLOCK,则 accept() 应阻塞,直到存在连接。如果 listen() 队列中没有连接请求,并且在套接字的文件描述符上设置了O_NONBLOCK,则 accept() 将失败并将 errno 设置为 [EAGAIN] 或 [EWILLBLOCK]。
来源: http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
此外,select
或poll
可用于通过轮询读取集中的侦听套接字来检查传入连接。
在问题中,您说您不想使用选择(或轮询或 epoll),这是 IO 多路复用的最佳方法。我建议您使用另一个线程仅用于侦听套接字,而这是一个坏主意!