C 带空fd集的套接字选择

C 带空fd集的套接字选择,c,select,sockets,C,Select,Sockets,假设您有一个fd集合,其中可以有零个或多个套接字。当我尝试调用空fd集合上的select操作时,我得到的是-1作为设置的fd数,这意味着错误。所以,您会建议如何克服这个问题,您可能会说,如果为空,则不要调用,但我有一个循环,并且任何时候fd set都可以容纳0个或更多套接字。解决这个问题的最佳方法是什么?(我们使用的是C编程语言)那是不对的。您应该能够指定0作为集合中文件描述符的数量。事实上,这就是我记得在早期使用select进行超时编码的方式,没有描述符,也没有适当设置超时值 如果返回-1,则

假设您有一个fd集合,其中可以有零个或多个套接字。当我尝试调用空fd集合上的select操作时,我得到的是-1作为设置的fd数,这意味着错误。所以,您会建议如何克服这个问题,您可能会说,如果为空,则不要调用,但我有一个循环,并且任何时候fd set都可以容纳0个或更多套接字。解决这个问题的最佳方法是什么?(我们使用的是C编程语言)

那是不对的。您应该能够指定0作为集合中文件描述符的数量。事实上,这就是我记得在早期使用
select
进行超时编码的方式,没有描述符,也没有适当设置超时值

如果返回-1,则需要查看
errno
以了解问题所在


啊,根据你的评论,
WSAEINVAL
的意思是WinSock。这就解释了你的问题。这是一只可怕的野兽,应该从我们的苦难中解脱出来:——)

说明如果超时值无效或所有三个描述符参数均为空,则将获得
WSAEINVAL
。它随后声明
FD_ZERO
“将集合初始化为空集合”。我不知道最后一个片段是否意味着该参数仍然被认为是空的。假设您的超时是正常的(因为如果您在其中一个集合中有一个FD,它就会工作),可能就是这种情况

我知道Berkeley sockets区分空FD集(即空指针)和空FD集(没有FDs集的有效指针)-WinSock可能没有那么多功能,特别是因为
nfds
被忽略,并且仅为了与Berkeley兼容而包含


我怀疑(尽管我不确定)WinSock可能希望您不要做您试图做的事情。它很可能只是假设您做错了什么,应该只对一个或多个FD集中的一个或多个套接字使用
select
(因为没有FDs的
select
的唯一用途是延迟,Windows有很多更好的延迟方式)。

请阅读帮助。它说,如果“超时值无效,或者所有三个描述符参数都为空”,将返回WSAEINVAL。很明显,您传递的超时值也不正确。因此,如果要与0描述符一起使用,请提供正确的超时值。

在Windows下,
select
函数完全忽略
nfds
参数。 我目前无法测试这个,但是如果所有集合都是非NULL但为空,则可能会返回错误


要解决此问题,您可以完全跳过select,或者保留一个虚拟套接字,以确保集合中始终至少有一个套接字。

是否调用
select
,并将其
nfds
参数设置为0?您使用的是什么平台?您可能还想发布代码,让我们的生活更轻松。Raymond Chen可能是一名枪械通灵调试器,但我们中的一些人更喜欢根据确凿的证据进行调试器:-)@Hasturkun-是的,nfds为0,我在Windows上事实上,它已通过FD_零启动为0,之后我调用select,但不知怎的,我得到了-1,错误为WSAEINVAL,但我只使用了读取FD集,但我得到了错误,但是如果我在其中设置了一个套接字,它就会工作…@paxdiablo-你可能是对的,Windows(行为不正常的家伙)只会忽略fd集是否为空。好的,事实上,正如你所说的,我已经阅读了这个解释,但我的参数s not NULL是空的…你在传递什么来表示超时,据我所知,select调用要求三个描述符集中至少有一个应该有一个值,或者超时值应该是正确的,否则select就不可能出现。对吗?如果您将所有三个描述符参数都传递为NULL,并且还提到了错误的超时,则select将永远阻止。您是对的,在Windows中忽略nfds,但我的参数不是NULL,而是空的。Windows看起来像是NULL。胡说..Linux比Windows处理得好得多!在Linux中,使用完全相同的参数调用select()返回0。另外,@Hasturkun,我已经在Windows和Linux上测试过了-我保证在Windows上它返回-1(SOCKET\u错误)。