2010-04-08 86 views
2

假設你有一個可以有零個或多個套接字的設置。當我嘗試調用空fd集上的select操作時,我得到的是-1作爲設置的fds的數量,這意味着錯誤。那麼你會怎麼建議來克服這個問題,你可能會說如果是空的話不會調用,但我有一個循環,任何時候fd set都可以容納0個或更多的套接字。關於這個問題的最佳方法是什麼? (我們使用C編程語言)套接字選擇空虛設置

+0

你是否將'nfds'參數設置爲0來調用'select'? 你在使用什麼平臺? – Hasturkun 2010-04-08 08:31:05

+0

您可能還想發佈代碼,讓我們的生活變得更輕鬆。雷蒙德陳可能是一個槍心靈調試器,但我們中的一些人喜歡從硬證據工作:-) – paxdiablo 2010-04-08 08:35:34

+0

@Hasturkun - 是的nfds是0,我在窗口 – whoi 2010-04-08 08:39:25

回答

6

這是不對的。您應該能夠指定0作爲集合中文件描述符的數量。實際上,這就是我記得早期使用超時代碼的原因,使用select時沒有描述符,並且超時值設置得當。

如果它返回-1,則需要查看errno以查看問題所在。


啊,根據你的評論,WSAEINVAL是指WinSock。這解釋了你的問題。這是一個可怕的野獸被趕出我們痛苦的:-)

This page here狀態,你會得到WSAEINVAL如果超時值無效或全部三個描述符參數爲null。它後來表明FD_ZERO「將該集初始化爲空集」。不管最後的片段是否意味着該參數仍然被認爲是NULL,我都不知道。假設你的超時時間沒有問題(因爲如果你在其中一個集合中有FD),那可能就是這種情況。我知道Berkeley套接字區分NULL FD集合(即NULL指針)和空FD集合(沒有FD集合的有效指針) - WinSock可能不是那種多功能的,特別是因爲nfds被忽略並僅包含與Berkeley兼容的內容。

我懷疑(雖然我不確定)WinSock可能希望你不要做你想做的事。它可能只是假設你做錯了什麼,並且應該只將select用於一個或多個FD集合中的一個或多個套接字(因爲沒有FD的select的唯一用途是延遲,而Windows有很多更好的方法延遲)。

+0

事實上,它已被啓動到0與FD_ZERO和事後我打電話選擇,但不知何故我得到-1,錯誤是WSAEINVAL,但我只是使用讀取FD設置,但我得到錯誤,但如果我在它設置一個套接字,它的工作原理... – whoi 2010-04-08 08:38:40

+0

@paxdiablo - 你可能是對的,如果fd集合是空的,Windows(那個不正確的行爲)就會忽略它。 – whoi 2010-04-08 09:48:49

-1

請閱讀select幫助。它說WSAEINVAL將被返回,如果「超時值無效,或者所有三個描述符參數都爲空。」 。很明顯,你也傳遞了一個不正確的超時值。所以,如果你想用0描述符來提供一個正確的timout值。

+0

其實,事實上,正如你所說我已經閱讀過這個解釋,但是我的論點s不是NULL是空的... – whoi 2010-04-08 09:46:43

+0

你通過了什麼超時? – Jay 2010-04-08 09:48:59

+0

在我的理解中,select調用期望三個描述符集中至少有一個應該有一個值,或者超時值應該是正確的,否則select就不會出現。對?如果您將所有三個描述符參數都作爲NULL傳遞並提及不正確的超時,那麼select將永遠阻塞。 – Jay 2010-04-08 09:50:58

1

在Windows下,select函數完全忽略nfds參數。 目前我無法測試它,但如果所有集合都非空而是空的,則可能會返回錯誤。

要解決此問題,您可以完全跳過選擇,或者保留一個虛擬套接字以確保套件中始終存在至少一個套接字。

+0

你是對的nfds在Windows中被忽略但是,我的參數不是NULL只是空的.Windows似乎威脅它是NULL。廢話.. – whoi 2010-04-08 09:47:45

+0

Linux處理這個比Windows好多了!在Linux中,使用完全相同的參數調用select()會返回0。 另外,@Hasturkun,我已經在Windows和Linux上測試過 - 我將在Windows上證實它返回-1(SOCKET_ERROR)。 – 2018-02-21 08:29:26