2008-09-15 86 views
80

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

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

socket.setSoTimeout(10000); 

直前readInt()へ:


私は、私は次の行を持っていることに注意してください。これには理由があります(長い話)が、好奇心が強いのですが、これが原因で指定されたエラーにつながる可能性がありますか?私はIDEを実行しているサーバを持っていて、IDEがブレークポイントに止まったままになってしまったので、まったく同じエラーが私のIDEの自分のログに現れ始めるのに気がつきました。

とにかく言えば、うまくいけば赤ちゃんではありません。 :-(

+0

両側にスタックトレースがありますか?ネットワークアーキテクチャについてもう少し説明できますか? (野生のインターネット上で、同じマシンで、どこかのどこかに)?それはいつも起こっていますか?または断続的に? –

答えて

8

私はこれに奇妙な問題があったときはいつも、WireSharkのようなツールを使って座って、渡された生のデータを見ています。あなたがしようと読んだときのみを通知されている。

31

接続単にあなたのピアは、それが処理できないデータを受信し、そのための様々な理由があることができたときにこれが発生します。TCP RSTを受信したことを意味し、リセット。

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

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


更新:

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

+0

いくつかの点では正しくありません。ガベージコレクションとプロセスは、どちらも適切なクローズを引き起こし、リセットは行われませんが、ピアが書き込みを終了すると、EOSではなくリセットが発生します。 SocketTimeoutExceptionsは、読み取り側が読み取りタイムアウトを設定した場合にのみ発生します。 – EJP

+0

それは必ずしもRSTが受信されたとは限りません。それは、この側によって1つが生成されたことを意味することもあります。 – EJP

+3

EJPはまだ5年後に塩辛いですか? – Daedric

81

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

  1. もう一方の端で意図的に接続をリセットしましたが、ここでは説明しません。アプリケーションソフトウェアがこれを行うのはまれで一般的に間違っていますが、市販のソフトウェアでは不明ではありません。

  2. より一般的には、もう一方の端がすでに正常に閉じている接続に書き込むことによって発生します。つまり、アプリケーションプロトコルエラーです。

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

  4. Windowsでは、 'ソフトウェアリセットによる接続の中止'は接続のリセットと同じではありませんが、あなたの最後から送信されるネットワークの問題が原因です。これに関するMicrosoftの知識ベースの記事があります。

+1

FYI http://support.microsoft.com/kb/204594 –

+0

@MattLyonsありがとうございます。それよりもはるかに優れたMSDN記事があります。率直に言って私はそれが信じがたいことがわかります。正しいソースとターゲットのIPアドレスが確立されるまで、接続は存在しません。私が見たMSDNの記事では、永続的なネットワークエラーが接続のタイムアウトを参照しています。 – EJP

3

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

+0

これは、この例外を単独では発生させません。 – EJP

+0

System.exit(0)がプログラムを強制終了し、接続が悪い状態で正しく閉じられなかったため、socket.close()を呼び出す人はいません。 soooはより適切には、ソケットを閉じずにシャットダウンするクライアントプログラムを持っていると言っていました;)これは悪いことであり、修正する必要があります。 –

+0

@DeanHillerいいえ、そうではありません。オペレーティングシステムは、アプリケーションに必要なのと同じ方法でソケットを閉じます。 – EJP

5

私はこの問題を抱えていましたが、すべてのデータを読み取る前に接続を切断していたのは間違いでした。小さな文字列が返された場合、それは機能しましたが、それはおそらく応答をすべてバッファリングしたためです。

返されるテキストの量が多い場合は、バッファが戻ってきてから例外がスローされました。

この監視を確認することがあります。 URLを開くのはファイルのようなものですが、完全に読み込まれたら必ず閉じてください(接続を解除してください)。

1

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

2

Javaで書かれたSOAシステムでこの問題が発生しました。私はクライアントとサーバーの両方を別々の物理マシン上で実行していましたが、長い間うまくいきました。クライアントログにこれらの不快な接続のリセットが現れ、サーバーログに何か変わったことはありませんでした。クライアントとサーバーの両方を再起動しても問題は解決しませんでした。最後に、サーバー側のヒープがいっぱいになっているため、JVMで使用できるメモリが増えました。問題は解決しました。ログにはOutOfMemoryErrorはありませんでした。メモリは枯渇していませんでした。

5

あなたは、私はサーバソケットアプリケーションをしたとjava.net.SocketException: Connection resetケースを固定し、非常に慎重に

を完全なトレースを検査する必要があります。

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

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

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

無限であることのこのソケットからの読み取りのためにあなたが読んしようとwhileループため、クライアントが私ServerSocketと思わrecursively.It自分自身を呼び出すis.read()何も送信せずにその接続を閉じるに接続する場合興味深いのは、for my JAVA Socketです閉じた接続から。 読み取り操作に以下のようなものを使用すると、その後

while(true) 
{ 
    Receive(); 
} 

あなたは以下のように、私はただのServerSocketを閉じて私の接続を更新し、さらに着信クライアント接続

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


//... 
} 

を待っていた何

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

にスタックトレースの何かを得ますこれにより、未知のクライアントソケットの紛失に対する私の接続が再確立されます

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を連続して得ている間にこのスナップショットを手に入れました。

enter image description here

関連する問題