检查套接字文件描述符是否可用?

4

如果我得到了一个文件描述符(套接字fd),如何检查该fd是否可用于读/写操作?在我的情况下,客户端已连接到服务器并且我们知道fd。然而,服务器将断开套接字,有没有线索可以检查它?

5个回答

5
您希望使用fcntl()函数来检查文件描述符的读/写设置:
#include <unistd.h>
#include <fcntl.h>

int    r;

r = fcntl(fd, F_GETFL);
if (r == -1)
        /* Error */
if (r & O_RDONLY)
    /* Read Only */
else if (r & O_WRONLY)
    /* Write Only */
else if (r & O_RDWR)
    /* Read/Write */

但这是一个与套接字不再连接时分开的问题。如果您已经在使用select()poll(),那么您就快完成了。如果您在events中指定POLLERR并在revents中检查它,则poll()会很好地返回状态。

如果您正在进行正常的阻塞I/O,那么只需在出现读/写错误时进行处理,并优雅地恢复即可。


这仅仅是检查文件锁定吗?那似乎有点不正规。 - andy_js

0
你可以使用 select() 或者 poll() 来实现这个功能。

0

在C#中,这个问题可以在这里找到答案。

一般来说,套接字的断开连接是异步的,并且需要以某种方式进行轮询。对套接字进行异步读取通常会返回其关闭状态,从而使您有机会更快地捕捉到状态变化。Winsock(Windows)具有注册接收断开连接通知的功能(但是,除非使用某种类型的“保持活动”(SO_KEEPALIVE,默认情况下可能几小时才能注意到,或应用程序级心跳),否则可能会在另一侧“消失”后很长时间才发生)。


0

我发现recv可以进行检查。当套接字fd出现问题时,会设置一些errno。

ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK); 
if(EPIPE == errno){
// something wrong
}

EPIPE并不意味着套接字FD有问题,而是表示连接已断开。这不是同一件事情。 - user207421

-1

嗯,你可以调用select()。如果服务器已经断开连接,我相信你最终会得到一个错误代码返回……如果没有,你可以使用select()来判断你的网络堆栈是否准备好发送更多数据(或接收数据)。


我认为如果远程端断开连接但没有返回任何错误,select可能会触发exceptfds参数。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接