Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 如何查找fdset中哪个套接字描述符变得无效_Sockets_Select - Fatal编程技术网

Sockets 如何查找fdset中哪个套接字描述符变得无效

Sockets 如何查找fdset中哪个套接字描述符变得无效,sockets,select,Sockets,Select,在服务器端对readfds执行select()时,它返回错误的文件描述符错误。如何在fdset中找到哪一个fd已无效?通常,当另一端的连接关闭或发送RST段时,select返回相应的描述符并将其标记为准备读取。随后从它们执行read/recv时,将返回错误或EOF 您还可以尝试使用strace工具(如果可用)进行调试。它将帮助您跟踪哪些描述符被送入select,哪些描述符被调用read/recv。您可以使用以下功能检查套接字上的挂起错误: int get_socket_error( int s

在服务器端对readfds执行select()时,它返回错误的文件描述符错误。如何在fdset中找到哪一个fd已无效?

通常,当另一端的连接关闭或发送RST段时,
select
返回相应的描述符并将其标记为准备读取。随后从它们执行
read
/
recv
时,将返回错误或EOF


您还可以尝试使用
strace
工具(如果可用)进行调试。它将帮助您跟踪哪些描述符被送入
select
,哪些描述符被调用
read
/
recv

您可以使用以下功能检查套接字上的挂起错误:

int get_socket_error( int s )  {
    int error;
    socklen_t len = sizeof( error );
    if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &error, &len ) < 0 ) 
        error = errno;
    return error;
}
int-get\u-socket\u错误(int-s){
整数误差;
socklen_t len=sizeof(错误);
if(getsockopt(s,SOL_SOCKET,SO_ERROR,&ERROR,&len)<0)
error=errno;
返回误差;
}

但正如@Maxim所说,从返回的
EBADF
通常是一种草率编码的指示,一旦我遇到这个错误,

在代码中…如果我在fdset中遍历每个fd并对每个fd执行fcntl(),我将能够找到哪个fd已无效。通常,在生成的read fdset中,您迭代所有标记为ready的描述符,并从中读取所需的数据。如果在读取后碰巧得到
-1
(或0,表示对等方关闭了套接字),这意味着错误已经发生,您不应该在下次调用
select
之前包含此描述符来读取fdset。否。如果我在select中遇到错误,我将对fdset中的每个fd执行fcntl。这会有帮助吗?您可能会通过这种方式检测到描述符有问题,但我从未见过这种操作。如果
select
返回
EBADF
,通常意味着您为其提供了无效的描述符。无效的事实(不存在文件描述符、闭合描述符或发生错误的描述符)应提前确定。确定..1基本问题…是否可以迭代fdset..任何人都知道fdset的结构…无法找到它。通常,fdset是一个位图,其中每一位都显示描述符是否准备就绪。但是,您不应该依赖于fdset的内部实现并使用宏来操作它(
FD_ISSET
etc)。通常的方法是从0到
max\u fd+1的循环
使用
fd\u ISSET
宏检查描述符是否已准备好IO。您正在迭代的当前变量包含一个文件描述符。如果您在Linux上,请切换到
epoll(7)
。您不必在每次迭代时重新填充等待列表,并且
close(2)
-ed套接字将自动从轮询集中删除。好的。对于windows,我可以使用ioctlsocket()检查套接字是否有效吗?也许,我不知道windows,但您正在尝试解决错误的问题-修复您的套接字处理。