TCP接続にSocketクラスを使用しています。しかし、私の現在の問題は、切断の理由を正確に判断することです。 どちらの場合も(接続タイムアウトまたはサーバー接続が閉じられている場合)、「破損パイプ」メッセージが表示されたSocketExceptionが表示されます。だから私は切断の理由を正確に判断する方法は?Javaでサーバが接続を切断した(RSTパケットを受信した)かどうかを確認するにはどうすればよいですか?
ありがとうございます!
TCP接続にSocketクラスを使用しています。しかし、私の現在の問題は、切断の理由を正確に判断することです。 どちらの場合も(接続タイムアウトまたはサーバー接続が閉じられている場合)、「破損パイプ」メッセージが表示されたSocketExceptionが表示されます。だから私は切断の理由を正確に判断する方法は?Javaでサーバが接続を切断した(RSTパケットを受信した)かどうかを確認するにはどうすればよいですか?
ありがとうございます!
私はあなたが別の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();
ちょっとした問題があります.SocketTimeoutExceptionは、読み取り操作で何も受け取らなかったとしても発生します。別の言葉で言えば、SocketTimeoutExceptionは接続が失われたことを保証するものではありません。これは、読み取りまたは受け入れコマンドのタイムアウトがあり、この間に何も受け取らなかった(あなたの場合は100ミリ秒)ということだけです。 – Zveroid
残念ながら、RSTパケットではなくFINフラグです。 – Zveroid
http://stackoverflow.com/questions/9868356/how-to-detect-fin-tcp-flag-in-java-applicationおよびhttp://stackoverflow.com/questions/6069218/how-do-javaに関連するアプリケーションに失敗しました。 – Gray