81


24

リモート側のソケットクローズを検出するにはどうすればいいですか?

リモート側のソケットで `Socket#close()`が呼び出されたかどうかをどうやって確認しますか?

4 Answer


60


isConnected`メソッドは役に立ちません。リモート側がソケットを閉じたとしても、 true`を返します。 これを試して:

public class MyServer {
    public static final int PORT = 12345;
    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(PORT);
        Socket s = ss.accept();
        Thread.sleep(5000);
        ss.close();
        s.close();
    }
}

public class MyClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket s = SocketFactory.getDefault().createSocket("localhost", MyServer.PORT);
        System.out.println(" connected: " + s.isConnected());
        Thread.sleep(10000);
        System.out.println(" connected: " + s.isConnected());
    }
}

サーバーを起動し、クライアントを起動します。 2回目にソケットが閉じられても、 "connected:true"が2回印刷されることがわかります。

実際に調べる唯一の方法は、関連するInput / OutputStreamを読み込むこと(戻り値として-1が返されるでしょう)または書くこと( IOException(壊れたパイプ)が投げられるでしょう)です。


26


答えが逸脱しているので、これをテストして結果を投稿することにしました - テスト例を含みます。

ここのサーバーはデータをクライアントに書き込むだけで、入力は一切期待していません。

サーバー:

ServerSocket serverSocket = new ServerSocket(4444); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream()、true); while(true){out.println( "output"); if(out.checkError())System.out.println( "ソケットへのデータ書き込み中にエラーが発生しました!!!"); System.out.println(clientSocket.isConnected()); System.out.println(clientSocket.getInputStream()。read()); //スレッドスリープ... //状態を壊し、ソケットを閉じるなど }
  • clientSocket.isConnected()は、クライアントが接続すると(そして切断された後も)変な場合は常にtrueを返します。

  • getInputStream()。read()クライアントが接続されている限りスレッドは入力を待機するため、プログラムは何もしません。クライアントが切断された場合は **を返します。

  • * out.checkError()はクライアントが切断されるとすぐにtrueになるのでこれをお勧めします*


13


クライアントソケットへの書き込み中にソケット出力ストリームエラーをチェックすることもできます。

out.println(出力)。 if(out.checkError()){新しい例外をスローします(「データ送信エラー」)。 }


-8


リモートシステムが接続を切断またはクローズした場合、Socket.Availableメソッドは直ちにSocketExceptionをスローします。