2010-09-02 106 views

回答

7

檢查該套接字的所有文件描述符是否已關閉。如果在「遠端」(假設這是你試圖關閉的那個端口)上的任何一個保持打開,則「peer has not performed an orderly shutdown」。

如果這仍然不起作用,請在遠程端調用shutdown(sock, SHUT_RDWR),這會關閉套接字,無論引用計數如何。

11

「爲什麼」就是這樣,它是如何工作的,通過設計。

在內核中,recv()通話呼籲對應的文件描述符struct filefget(),這將防止其被釋放到相應的fput()

你只需要改變你的設計(設計本身就是活潑無論如何 - 要做到這一點,你必須沒有鎖定保護在用戶空間的文件描述符,這意味着close()可能的前剛剛發生recv()調用 - 文件描述符甚至被重用於其他事情)。


如果你想喚醒另一個線程的阻止一個文件描述符,你應該有它select()阻止相反,與包括在可以被主線程寫入文件描述符集管。

+0

如果我在調用recv之前調用close,它應該可以工作,但是一旦調用在recv中,並且如果我從另一個線程調用close,它就不會被釋放。它是否正確? – Jay 2010-09-02 10:37:34

+6

@Jay:一旦你調用close(),你就不應該在文件描述符上調用recv()。如果你幸運的話,你只會得到'EBADF',但如果你不幸,你可以從另一個線程新打開的完全不同的套接字中讀取。 – caf 2010-09-02 11:35:32

+0

我認爲你錯過了這一點。 Pater試圖在recv()內的ALREADY套接字上調用close()來強制recv()立即退出。這適用於其他系統,但不適用於Linux。 – 2010-09-02 21:47:53