2011-06-20 44 views
3

在多線程應用程序中,我有一個線程從套接字連接讀取數據,直到發生讀取超時。然後設置一個關閉標誌,發送一箇中斷信號並在退出之前進行一些清理。作爲該清理的一部分,它在客戶端套接字上調用close()Socket.close()如何失敗(不引發異常)?

我在調試器中驗證了實際發生的close()的調用。另外,它不會拋出異常。不過,套接字報告正在連接。我知道,因爲有另一個線程wait爲它斷開連接。此線程稍後應重新連接它,但不會因爲調用isConnected()不斷返回true

這會導致無法讀取數據以及套接字被重新清理並重新連接的情況。

如果調用Socket.close(),有沒有什麼辦法可以默默地失敗?

+0

當你關閉一個套接字時,它必須在兩端關閉才能完全移除。你是否在兩端調用close()? –

+2

一旦套接字關閉,您將無法重新連接套接字;從'Socket.close()'的'javadoc':'一旦套接字被關閉,它就不能用於進一步的網絡使用(即不能重新連接或反彈)。需要創建一個新的套接字。# – artbristol

+0

@artbristol - 感謝那個指針。 –

回答

5

isConnected並不意味着「連接到服務器」「曾經被連接」。如果您想知道套接字是否已關閉,請使用isClosed

0

我不知道有任何這樣的行爲。也許第二個線程會有更多的運氣叫isClosed

1

isConnected()並不意味着你的想法。如果我記得正確的話,我將永遠保持真實。

編輯:從documentation

true if the socket successfuly connected to a server

這意味着,當你得到它斷開不會成爲虛假。

編輯2:我看到其他一些答案建議您檢查isClosed。請注意,如果您調用close(),則isClosed僅返回true。如果另一方關閉連接,它不會自動開始返回true。

1

結合artbristol的評論,凱伊的和dawce的答案和一些額外的診斷我所做的,完整的答案是:

  1. close()可能並沒有失敗。您不能使用isConnected()檢查套接字的當前連接狀態,這隻會告訴您是否有成功的連接。撥打電話isClosed()會告訴你,close()之前是否已經打過電話。

  2. 在調試過程中,數據包嗅探器可以在您逐步執行代碼時向您顯示線路上發生了什麼。對於你的例子,這應該表明連接確實在網絡層上關閉,即。即,你應該看到FIN和相應的ACK數據包,然後就不會再有了。

  3. 如果您確定套接字已關閉,則無法重新連接或重新綁定套接字。相反,你必須創建一個新的套接字。

0

對於有人來到這裏想知道如何檢查Socket是否關閉。

socket.isConnected() && socket.isClosed()