Sockets 如何查找fdset中哪个套接字描述符变得无效
在服务器端对readfds执行select()时,它返回错误的文件描述符错误。如何在fdset中找到哪一个fd已无效?通常,当另一端的连接关闭或发送RST段时,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
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,但您正在尝试解决错误的问题-修复您的套接字处理。