2016-06-27 44 views
1

這是一個非常基本的問題,但我不能爲它找到任何地方一個明確的答案:ServerSocketChannel.accept()返回的SocketChannel是否保證連接?

當我accept()從的ServerSocketChannel的連接,我是保證返回的SocketChannel是「connected」,或可能呢發生返回的頻道仍在執行某種形式的握手或其他任何操作,只會稍後將其設置爲SelectionKey.OP_CONNECT位?

換句話說,我是保證,下面的代碼片段將從未打印false

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 
serverSocketChannel.socket().bind(new InetSocketAddress(1234)); 
SocketChannel socketChannel = serverSocketChannel.accept(); 
System.out.println(socketChannel.isConnected()); 
+0

_如果此通道處於非阻塞模式,那麼如果沒有掛起的連接,此方法將立即返回null。否則,**將無限期阻止,直到出現新的連接**或發生I/O錯誤。似乎表明它將被連接。 –

+0

@SotiriosDelimanolis「似乎」正是這個問題! ;)連接在完全「連接」之前可能已被視爲「可用」。也許......我不知道......我希望他們對此更加清楚...... –

回答

3

ServerSocketChannelImplServerSocketChannelImpl源創建具有ST_CONNECTED的狀態的SocketChannelImpl

由於SocketChannelImpl.isConnected()方法檢查ST_CONNECTED狀態,所以測試應始終返回true。

然而,這是美好時光的情景。可能發生的情況是,服務器線程被延遲,並且在線程調用isConnected()時,客戶端已關閉連接。

所以,不,不能保證你的代碼永遠不會打印錯誤。

+0

看起來不錯。謝謝! +1,√ –

0

SocketChannel和底層套接字的狀態是獨立的,直到通過讀/寫操作同步爲止。有不能保證插座仍然打開後調用accept()

所以基本上,SocketChannel.isConnected()總是去調用accept()後返回TRUE 但本質上是一個猜測。它並不真正知道!測試這個的唯一方法是嘗試讀取/寫入一些數據到SocketChannel

將數據寫入通道將顯示套接字是否仍在遠程計算機上打開。您可以通過使用交換機連接客戶端和服務器,然後移除其中一臺計算機的網絡電纜來測試此行爲。你會看到插座將會很長時間保持打開狀態。有一些套接字選項可以用來緩解這一點,但不是太多。

SocketChannel中讀取只顯示,如果read()返回-1,它將被關閉;

相關問題