場景:
連接的客戶機和server.The客戶端連接之間建立關閉客戶端被破壞。在服務器端,一些連接關閉被檢測到,但有些不是。所以有一些socket描述符就像懸掛指針一樣。選擇這些返回錯誤的文件描述符錯誤,但不可能找到無效的fd。方法來處理錯誤的文件描述符錯誤
問題: 在上述情況下,當客戶端連接不存在我應該怎麼處理這些BAD FILE DESCRIPTORs
。可我呼籲這些recv()
?
場景:
連接的客戶機和server.The客戶端連接之間建立關閉客戶端被破壞。在服務器端,一些連接關閉被檢測到,但有些不是。所以有一些socket描述符就像懸掛指針一樣。選擇這些返回錯誤的文件描述符錯誤,但不可能找到無效的fd。方法來處理錯誤的文件描述符錯誤
問題: 在上述情況下,當客戶端連接不存在我應該怎麼處理這些BAD FILE DESCRIPTORs
。可我呼籲這些recv()
?
爲select()
的簽名是:
int select(int nfds, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict errorfds,
struct timeval *restrict timeout);
不會在errorfds
集給你這一個錯誤條件描述符的列表,如EBADF
?
您可以調用recv()
或任何其他函數,該文件描述符帶有文件描述符;您可能會從所調用的函數中返回EBADF
錯誤(除非在檢測到EBADF
之前檢測到其他錯誤情況)。
我相信你搞砸了不同的情況。如果連接在客戶端關閉,並且您在服務器端套接字上調用select(),則會觸發FD_READ並且recv()將返回零,然後您可以在服務器端關閉套接字。
如果連接中斷並且服務器未收到FIN信號,則需要在客戶端&服務器和每個服務器端套接字上的計時器之間檢測心跳,以檢測TCP半開狀態。
只有在已關閉的套接字上調用API時,纔會出現「錯誤文件描述符」錯誤。
所以你的意思是在TCP半開放的情況下select會返回一個EBADF? – user1495948
否。對於TCP半開放套接字,select()將不返回任何內容,也不返回事件,也不寫入事件。通常使用心跳計時器來檢測TCP半開放式套接字,然後關閉它。 – ciphor
爲什麼一個套接字描述符變得不好選擇返回錯誤的文件描述符和recv返回0? – user1495948
recv()在這種情況下返回0,就好像與客戶機的連接已關閉,但select爲相同的套接字描述符返回錯誤的文件描述符。 – user1495948
您可能需要區分系統認爲的「壞文件描述符」和您認爲的壞文件描述符。系統認爲已關閉(或從未打開)的文件描述符不好。僅僅在讀描述符的遠端沒有發送者的事實不是錯誤;文件描述符可能被報告爲'準備好',並且當你讀取它時,你會得到EOF指示(它是零字節讀取的)。文件描述符不錯;它永遠不會返回任何數據。當'recv()'調用返回零時,您認爲客戶端已經消失。 –
我關閉客戶端的連接,同時在服務器端如果我選擇fd獲取集,我做recv()返回0,我斷定客戶端是closed.But在某些情況下選擇將返回錯誤文件描述符error.Do你知道在哪種情況下選擇返回描述符上的EBADF? – user1495948