2012-03-29 26 views
0

TCP接続にSocketクラスを使用しています。しかし、私の現在の問題は、切断の理由を正確に判断することです。 どちらの場合も(接続タイムアウトまたはサーバー接続が閉じられている場合)、「破損パイプ」メッセージが表示されたSocketExceptionが表示されます。だから私は切断の理由を正確に判断する方法は?Javaでサーバが接続を切断した(RSTパケットを受信した)かどうかを確認するにはどうすればよいですか?

ありがとうございます!

+0

残念ながら、RSTパケットではなくFINフラグです。 – Zveroid

+0

http://stackoverflow.com/questions/9868356/how-to-detect-fin-tcp-flag-in-java-applicationおよびhttp://stackoverflow.com/questions/6069218/how-do-javaに関連するアプリケーションに失敗しました。 – Gray

答えて

0

私はあなたが別のExceptionがスローされるべきだと思います。あなたが接続について話しているなら、リセットを送信するホストからSocketExceptionを取得する必要があります(これはパケットだと思います)。接続がタイムアウトするとSocketTimeoutExceptionになります。

サーバーが接続をドロップした場合、あなたがSocketExceptionしばらく出IO回数(多分ちょうど読み込みが)あなたが取得する場合SocketTimeoutExceptionを取得します、その後、再びIOについて話している場合。

私が使ったテストプログラムは次のとおりです。もちろん、私は狂ったようにソケットを出血しています。

try { 
     new Socket().connect(new InetSocketAddress(someIpThatHangs, 8000), 1000); 
     fail("Should have thrown"); 
    } catch (SocketTimeoutException e) { 
     // we expected it to timeout 
    } 
    try { 
     new Socket().connect(new InetSocketAddress(someIpThatResets, 1000)); 
     fail("Should have thrown"); 
    } catch (SocketException e) { 
     // we expected it to throw an exception immediately on reset 
    } 

    // start our server 
    final ServerSocket serverSocket = new ServerSocket(); 
    int serverPort = 8000; 
    InetSocketAddress address = new InetSocketAddress("127.0.0.1", serverPort); 
    serverSocket.bind(address); 
    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       try { 
        Socket clientSocket = serverSocket.accept(); 
        System.err.println("Got a connection"); 
        Thread.sleep(1000); 
        clientSocket.close(); 
       } catch (InterruptedException e) { 
        return; 
       } catch (Exception e) { 
        e.printStackTrace(); 
        return; 
       } 
      } 
     } 
    }); 
    thread.start(); 

    // wait for the server to start 
    Thread.sleep(100); 
    Socket clientSocket = new Socket(); 
    clientSocket.connect(address); 

    try { 
     // read until the server closes the connection 
     clientSocket.getInputStream().read(); 
    } catch (SocketException e) { 
     // expected socket exception 
    } 

    clientSocket = new Socket(); 
    clientSocket.connect(address); 
    clientSocket.setSoTimeout(100); 

    try { 
     // read until the socket timeout expires 
     clientSocket.getInputStream().read(); 
    } catch (SocketTimeoutException e) { 
     // expected read timeout exception 
    } 

    serverSocket.close(); 
    thread.interrupt(); 
+0

ちょっとした問題があります.SocketTimeoutExceptionは、読み取り操作で何も受け取らなかったとしても発生します。別の言葉で言えば、SocketTimeoutExceptionは接続が失われたことを保証するものではありません。これは、読み取りまたは受け入れコマンドのタイムアウトがあり、この間に何も受け取らなかった(あなたの場合は100ミリ秒)ということだけです。 – Zveroid

関連する問題