如果我得到了一个文件描述符(套接字fd),如何检查该fd是否可用于读/写操作?在我的情况下,客户端已连接到服务器并且我们知道fd。然而,服务器将断开套接字,有没有线索可以检查它?
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,那么只需在出现读/写错误时进行处理,并优雅地恢复即可。
select()
或者 poll()
来实现这个功能。在C#中,这个问题可以在这里找到答案。
一般来说,套接字的断开连接是异步的,并且需要以某种方式进行轮询。对套接字进行异步读取通常会返回其关闭状态,从而使您有机会更快地捕捉到状态变化。Winsock(Windows)具有注册接收断开连接通知的功能(但是,除非使用某种类型的“保持活动”(SO_KEEPALIVE,默认情况下可能几小时才能注意到,或应用程序级心跳),否则可能会在另一侧“消失”后很长时间才发生)。
我发现recv可以进行检查。当套接字fd出现问题时,会设置一些errno。
ret = recv(socket_fd, buffer, bufferSize, MSG_PEEK);
if(EPIPE == errno){
// something wrong
}
嗯,你可以调用select()。如果服务器已经断开连接,我相信你最终会得到一个错误代码返回……如果没有,你可以使用select()来判断你的网络堆栈是否准备好发送更多数据(或接收数据)。
select
可能会触发exceptfds参数。 - Ben Voigt