gpt4 book ai didi

我能否保证在 select() 报告套接字已准备好读取后 recv() 不会阻塞?

转载 作者:太空狗 更新时间:2023-10-29 16:12:27 25 4
gpt4 key购买 nike

背景:我知道我不能在 select() 之后直接调用 accept() 并假设它会工作,因为那里客户端有可能在 select() 返回后断开连接,即使 select() 告诉我套接字已准备好接受 accept() .相反,我需要将套接字设置为 O_NONBLOCK,然后在调用 accept() 时测试 EAGAIN/EWOULDBLOCK - 见下文。

问题:我是否需要对 select()/recv() 做同样的事情?如果 select() 告诉我套接字已准备好读取,我可以调用 recv() 并保证它不会阻塞(或报告 EAGAIN/EWOULDBLOCK 如果它是一个非阻塞套接字)?

这是我在 accept() 案例中使用的代码:

    while(true) {
fd_ready = select_for_read(listen_fds, 2);
fd_client = accept(fd_ready, (struct sockaddr *)&client_addr, &client_addr_len);
if (fd_client == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
} else {
exit_with_error("Error accepting connection from client");
}
}
break;
}

(select_for_read 获取一组文件描述符并阻塞,直到准备好使用 select() 读取。)

最佳答案

来自select man page for Linux :

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination
has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

当然,该警告出现在错误部分,暗示作者认为这不是预期的行为——但无论如何,至少在 Linux 下这是可能发生的事情。就个人而言,我总是将我的套接字设置为非阻塞的;这样我就不必担心我的程序意外地阻塞了我打算阻塞的地方以外的任何地方(即在 select() 内部)。

关于我能否保证在 select() 报告套接字已准备好读取后 recv() 不会阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23577888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com