156

ソケットから読み取ろうとすると、次のエラーが発生します。私はそれをやっていreadInt()ますInputStreamが、このエラーが発生しています。ドキュメントを熟読すると、これは、接続のクライアント部分が接続を閉じたことを示唆しています。このシナリオでは、私がサーバーです。

クライアントのログ ファイルにアクセスできますが、接続を閉じていません。実際、そのログ ファイルは、接続を閉じていることを示しています。なぜこれが起こっているのか誰にも分かりますか?他に何を確認しますか?これは、おそらくしきい値に達しているローカル リソースがある場合に発生しますか?


次の行があることに注意してください。

socket.setSoTimeout(10000);

の直前readInt()。これには理由があります (長い話) が、興味深いことに、これが示されたエラーにつながる可能性がある状況はありますか? IDE でサーバーを実行していて、たまたま IDE がブレークポイントで動かなくなったままになり、IDE の自分のログにまったく同じエラーが表示され始めたことに気付きました。

とにかく、それについて言及するだけで、うまくいけば赤いニシンではありません. :-(

4

13 に答える 13

130

いくつかの原因が考えられます。

  1. 反対側は意図的に接続をリセットしましたが、これについてはここでは説明しません。アプリケーションソフトウェアがこれを行うことはまれであり、一般的には正しくありませんが、商用ソフトウェアでは不明ではありません.

  2. より一般的には、相手側が既に正常に閉じているという接続への書き込みが原因です。つまり、アプリケーション プロトコル エラーです。

  3. また、ソケットの受信バッファに未読のデータがあるときにソケットを閉じることによっても発生する可能性があります。

  4. Windows では、「接続のリセット」とは異なる「ソフトウェアが原因で接続が中止されました」は、ユーザー側から送信するネットワークの問題が原因です。これに関するマイクロソフトのナレッジ ベースの記事があります。

于 2010-11-29T04:11:56.193 に答える
59

接続のリセットは、単に TCP RST が受信されたことを意味します。これは、ピアが処理できないデータを受信したときに発生します。これにはさまざまな理由が考えられます。

最も単純なのは、ソケットを閉じてから、出力ストリームにさらにデータを書き込む場合です。ソケットを閉じることで、ピアに話が終わったことを伝え、接続を忘れることができます。とにかくそのストリームでさらにデータを送信すると、ピアは RST でそれを拒否し、リッスンしていないことを知らせます。

他のケースでは、介在するファイアウォールまたはリモート ホスト自体でさえ、TCP 接続を「忘れる」可能性があります。これは、長時間データを送信しなかった場合 (一般的なタイムアウトは 2 時間)、またはピアが再起動されてアクティブな接続に関する情報が失われた場合に発生する可能性があります。これらの無効な接続の 1 つでデータを送信すると、RST も発生します。


追加情報に応じて更新します。

の取り扱いをよく見てくださいSocketTimeoutException。この例外は、ソケット操作でブロックされている間に構成されたタイムアウトを超えた場合に発生します。この例外がスローされても、ソケット自体の状態は変更されませんが、例外ハンドラーがソケットを閉じてから書き込みを試みると、接続がリセットされた状態になります。別のスレッドからソケットを閉じるなどの汚いことをせずに、そうでなければ永久にブロックされる可能性setSoTimeout()のある操作から抜け出すためのクリーンな方法を提供することを目的としています。read()

于 2008-09-15T14:03:55.430 に答える
20

このような奇妙な問題が発生したときはいつでも、私は通常、WireSharkのようなツールを使用て、前後に渡される生データを確認します。物事が切断されていることに驚かれるかもしれません、そしてあなたが試みて読んだときだけあなたは通知されます。

于 2008-09-15T13:45:06.427 に答える
12

完全なトレースを非常に注意深く検査する必要があります。

サーバー ソケット アプリケーションがあり、java.net.SocketException: Connection resetケースを修正しました。

Socket私の場合、何らかの理由で接続が閉じられている clientSocket オブジェクトからの読み取り中に発生します。(ネットワークが失われた、ファイアウォールまたはアプリケーションがクラッシュした、または意図的に閉じた)

この Socket オブジェクトからの読み取り中にエラーが発生したとき、実際には接続を再確立していました。

Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!

興味深いことにfor my JAVA Socket、クライアントが my に接続し、ServerSocket何も送信せずにその接続を閉じるis.read()と、繰り返し呼び出されます。このソケットから読み取るための無限 while ループにあるため、閉じられた接続から読み取ろうとしているようです。読み取り操作に以下のようなものを使用する場合;

while(true)
{
  Receive();
}

次に、以下のようなstackTraceを何度も取得します

java.net.SocketException: Socket is closed
    at java.net.ServerSocket.accept(ServerSocket.java:494)

私がしたことは、ServerSocketを閉じて接続を更新し、さらに着信クライアント接続を待つことです

String Receive() throws Exception
{
try {                   
            int readed = is.read();
           ....
}catch(Exception e)
{
        tryReConnect();
        logit(); //etc
}


//...
}

これにより、未知のクライアントソケットが失われた場合に接続が再確立されます

private void tryReConnect()
        {
            try
            {
                ServerSocket.close();
                //empty my old lost connection and let it get by garbage col. immediately 
                clientSocket=null;
                System.gc();
                //Wait a new client Socket connection and address this to my local variable
                clientSocket= ServerSocket.accept(); // Waiting for another Connection
                System.out.println("Connection established...");
            }catch (Exception e) {
                String message="ReConnect not successful "+e.getMessage();
                logit();//etc...
            }
        }

下の画像からわかるtry and catchように、すべてが正しいように見えるため、接続が失われたかどうかを . Connection reset継続して取得しているときに、このスナップショットを取得しました。

ここに画像の説明を入力

于 2015-07-31T08:20:59.590 に答える
10

恥ずかしい話ですが、この問題が発生したとき、すべてのデータを読み取る前に接続を閉じていたのは単純な間違いでした。小さな文字列が返される場合はうまくいきましたが、それはおそらく、閉じる前に応答全体がバッファリングされたためです。

より長い量のテキストが返された場合、より多くのバッファが返されたため、例外がスローされました。

この見落としがないか確認してください。URL を開くことはファイルのようなものであることを忘れないでください。完全に読み取られたら、必ず閉じてください (接続を解放してください)。

于 2013-07-23T17:10:23.417 に答える
7

同じエラーが発生しました。私は今問題の解決策を見つけました。問題は、サーバーがストリームを読み取る前にクライアント プログラムが終了していたことです。

于 2011-03-27T20:30:13.277 に答える
1

SSH 経由でサーバーにコマンドを送信しようとする Java プログラムでも、この問題が発生しました。問題は、Java コードを実行するマシンにありました。リモートサーバーに接続する権限がありませんでした。write() メソッドは正常に動作していましたが、read() メソッドは java.net.SocketException: Connection reset をスローしていました。クライアントSSHキーをリモートサーバーの既知のキーに追加することで、この問題を修正しました。

于 2014-07-10T16:07:53.260 に答える
0

私の経験では、次のような状況によく遭遇します。

  1. 企業で働いている場合は、ネットワークおよびセキュリティ チームに連絡してください。外部サービスへのリクエストでは、関連するエンドポイントに許可を与える必要がある場合があるためです。

  2. もう 1 つの問題は、アプリケーションが実行されているサーバーでSSL 証明書の有効期限が切れている可能性があることです。

于 2020-06-05T14:00:44.827 に答える