假设您有一个fd集,其中可以包含零个或多个套接字。当我尝试在空fd set上调用select操作时,得到的是-1作为设置的fds的数量,这意味着错误。那么你会建议如何克服这个问题,你可能会说如果空的话不要调用但我有一个循环,任何时候fd set都可以容纳0个或更多的套接字。关于这个问题的最佳方法是什么? (我们使用的是C编程语言)
答案 0 :(得分:6)
那不对。您应该能够将0指定为集合中的文件描述符数。实际上,这就是我记得在早期使用select
而没有描述符和适当设置超时值的超时代码。
如果它返回-1,您需要查看errno
以查看问题所在。
啊,根据您的评论,WSAEINVAL
表示WinSock。这解释了你的问题。这是一个可怕的野兽,应该摆脱我们的苦难: - )
This page here表示如果超时值无效或者所有三个描述符参数都为空,您将获得WSAEINVAL
。它后来声明FD_ZERO
“将集合初始化为空集”。是否最后一个片段意味着该参数仍被视为NULL,我不知道。假设您的超时是可以的(因为如果您在其中一个集合中有FD,它可以工作),那可能就是这种情况。
我知道Berkeley套接字区分NULL FD集(即NULL指针)和空FD集(没有设置FD的有效指针) - WinSock可能不是那么通用,特别是因为{{1}被忽略,仅包括与Berkeley的兼容性。
我怀疑(虽然我不确定)WinSock可能会期待你不要做你想做的事情。它可能只是假设您做错了,并且应该仅将nfds
用于一个或多个FD集中的一个或多个套接字(因为select
没有FD的唯一用途是延迟并且Windows有很多更好的延迟方法。)
答案 1 :(得分:1)
在Windows下,select
函数完全忽略nfds
参数。
我目前无法对此进行测试,但如果所有集合都为非NULL但为空,则可能会返回错误。
要解决此问题,您可以完全跳过选择,也可以保留一个虚拟套接字以确保套件中始终至少有一个套接字。
答案 2 :(得分:0)
请阅读select帮助。它表示如果“超时值无效,或者所有三个描述符参数都为空”,则返回WSAEINVAL。 。很明显,你也传递了一个不正确的超时值。因此,如果要使用0描述符,请提供正确的时间值。