2016-06-27 4 views
1

は、これはかなり基本的な質問ですが、私はどこにもそれのために決定的な答えを見つけることができません:それを私accept()のServerSocketChannelからの接続は、私が返されたSocketChannelが「connected」であることを保証していた場合ServerSocketChannel.accept()によって返されるSocketChannelは確実に接続されていますか?

、または可能性返されたチャンネルがまだ何らかの形でハンドシェイクなどを実行していて、後でその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を返した場合にクローズされます。

関連する問題