「ソフトウェアによる接続アボート:ソケット書き込みエラー」の正式な理由


157

このスタックトレーススニペットを考える

原因:java.net.SocketException:ソフトウェアが接続を中止しました:
 java.net.SocketOutputStream.socketWrite0(Native Method)でのソケット書き込みエラー

私は次の質問に答えようとしました:

  1. この例外をスローしているコードは何ですか?(JVM?/ Tomcat?/ My code?)
  2. この例外がスローされる原因は何ですか?

#1について:

SunのJVMソースにはこの正確なメッセージは含まれていませんが、「ソフトウェアによって接続が中止されました」というテキストが表示されると思います。ソケットの書き込みエラーは、SocketOutputStream

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

#2について

私の推測では、完全な応答を取得する前にクライアントが接続を終了したときに発生します(たとえば、要求を送信したが、完全な応答を取得する前に、閉じられた/終了した/オフラインになった)。

質問:

  1. 上記の仮定は正しいですか(#1および#2)?
  2. これは「サーバー側のネットワークエラーのため、クライアントに書き込むことができませんでした」という状況と区別できますか?それとも同じエラーメッセージが表示されますか?
  3. そして最も重要なこと:上記について述べた公式文書(Sunなど)はありますか?

このスタックトレースがソケットクライアントの「障害」であることを証明する必要があります。サーバーがそれを回避するためにできることは何もありません。(例外のキャッチ、またはSun JVM以外のSocketOutputStreamの使用を除いて、どちらもクライアントが終了したという事実を実際には回避しません)


Firefoxでダウンロードをキャンセルするとこの問題が発生します
koppor 2013年

(書き込み/送信中にちょっとエランまた、私はこの例外を取得していますouts.write(audioBytes);byte[]にしてOutputStream。オーディオが鳴っているとき、およびユーザーが他のメニュー(サーバーリクエストを送信する)をクリックすると再生中に、コンソールで同じエラーが発生しました。この例外を無視しても安全ですか?
Amogh

1
@Amogh-そうですね、そうです。基本的に答えが説明していることから、これはWindows固有のエラーですが、Linuxでは別の表現で同じ例外が発生すると思います...(私の一般的な用語は、これを送信すると発生するということです。ソケットを介してリモートロケーションXとXが途中で切断されましたが、それを説明する最も正確な方法ではないと思います)
Eran Medan

1
私にとってこれは、データベースサーバーが再起動され、アプリケーションが以前に開かれた接続を使用してクエリを実行しようとしたときに起こりました。DBCPベースのプールを使用しているため、これらが更新されなかった理由がわかりません。しかし、アプリケーションを再起動すると問題が解決しました。
Kshitiz Sharma 2017

回答:


55

このエラーは、データの再送信が失敗した後にWinSockが確立された接続を閉じた場合など、ローカルネットワークシステムが接続を中止した場合に発生する可能性があります(受信側はデータストリームソケットで送信されたデータを確認しません)。

このMSDNの記事を参照してください「ソフトウェアによる接続の中止」に関する情報も参照してください。



3
@MatGesselその記事は混乱を繰り返し、独自の記事をいくつか追加しています。WSAECONNABORTEDはWinsockエラーコードであるため、バークレーの説明はありません。HTTPサーバーについて説明した状況では、WSAECONNABORTEDではなくECONNRESETが生成されます。
ローン侯爵

@EJP、([outs.write(audioBytes);)byte []をOutputStreamに送信/書き込みしているときにもこの例外が発生します。オーディオが鳴っているとき、およびユーザーが他のメニュー(サーバーリクエストを送信する)をクリックすると再生中に、コンソールで同じエラーが発生しました。この例外を無視しても安全ですか?
Amogh

1
@rustyxここで引用されている3つのソースはすべて、ACK障害によって生成されたと述べています。あなた自身の主張の情報源があればそれを引用してください。
ローン侯爵、2015年

2
これは、問題をさらに追求するための情報を提供しないため、本当の答えではありません。ここでの答えは、基本的に「ネットワーク上で何か問題が発生しました」です。今後のログやその他のアクティビティの記録によって、根本的な問題を特定できるとしたら、それは非常に役立ちます。
デレクベネット

11

java.net.SocketException作成またはアクセスエラーが発生した場合にスローされるソケット(例えば、TCP)。これは通常、サーバーが接続を(適切に閉じずに)終了したため、完全な応答を取得する前に発生する可能性があります。ほとんどの場合、これはタイムアウトの問題(応答に時間がかかりすぎるか、サーバーが要求で過負荷になっているなど)、またはクライアントがSYNを送信したが、ACKを受信しなかった(接続終了の確認)のいずれかが原因です。 。タイムアウトの問題については、タイムアウト値を増やすことを検討できます。

ソケット例外には通常、問題に関する特定の詳細メッセージが付属しています。

詳細なメッセージの例:

  • ソフトウェアによって接続が中止されました:recvが失敗しました。

    このエラーは、メッセージを送信しようとしたことを示し、接続はサーバーによって中止されました。データベースへの接続中にこれが発生した場合、これは互換性のないConnector / J JDBCドライバーの使用に関連している可能性があります

    考えられる解決策:CLASSPATHに適切なライブラリー/ドライバーがあることを確認してください。

  • ソフトウェアによって接続が中止されました:接続。

    これは、リモートへの接続に問題がある場合に発生する可能性があります。たとえば、ウイルスチェッカーがリモートメール要求を拒否したことが原因です。

    考えられる解決策:ウイルススキャンサービスで、接続の送信要求のポートがブロックされているかどうかを確認します。

  • ソフトウェアにより接続が中止されました:ソケット書き込みエラー。

    考えられる解決策:正しいバイト長をストリームに書き込んでいることを確認してください。そのため、送信する内容を再確認してください。このスレッドを参照してください。

  • ピアによる接続のリセット:ソケット書き込みエラー/ピアによる接続の中止:ソケット書き込みエラー

    アプリケーションは、キープアライブ接続がサーバー側でタイムアウトになったかどうかを確認しませんでした。

    考えられる解決策:接続から読み取る前に、HttpClientがnull以外であることを確認します。E13222_01

  • ピアによって接続がリセットされました。

    接続はピア(サーバー)によって終了されました。

  • 接続がリセットされました。

    接続は、要求による要求が原因で、クライアントによって終了されたか、接続のサーバー側によって閉じられました。

    参照:java.net.SocketException:接続のリセットの原因は何ですか?


これらの6つのポイントのうち1つだけが実際に質問に正しく答えていません。他のいくつかも同様に正しくありません。アプリケーションは、「サーバー側でキープアライブ接続がタイムアウトになったかどうかを確認できません」。HttpClientビーイングはnull、おそらく原因とすることはできませんSocketException。正しい長さをストリームに書き込まないこともできません。
ローン侯爵

9

ワークステーション/ラップトップの企業ファイアウォールが邪魔になり、接続が切断されるときに、これをよく目にしました。

例えば。同じマシン上にサーバープロセスとクライアントプロセスがあります。サーバーはすべてのインターフェース(0.0.0.0)をlistenしており、クライアントはpublic / homeインターフェースへの接続を試みます(ループバックインターフェース127.0.0.1ではないことに注意してください)。

マシンのネットワークが切断されている(wifiがオフになっているなど)場合、接続が形成されます。マシンが企業ネットワークに(直接またはVPNで)接続されている場合、接続が形成されます。

ただし、マシンがパブリックwifi(またはホームネットワーク)に接続されている場合、ファイアウォールは接続を強制終了します。この状況では、クライアントをループバックインターフェイスに接続することは、ホーム/パブリックインターフェイスではなく、正常に機能します。

お役に立てれば。


3
ファイアウォールは接続を防ぎます。問題は、既存の接続をリセットすることです。
ローン侯爵

4

どのコンポーネントに障害が発生したかを証明するには、wiresharkを使用してTCP / IP通信を監視し、ポートを実際に閉じているのが誰かを確認します。また、タイムアウトも関係する可能性があります。


誰もポートを閉じていません。オペレーティングシステムは接続を中止しています。
ローン侯爵2014年

@EJP私は、これが過負荷になり、メモリが不足したときに発生することを見ました。接続を閉じるのはOSかどうかはわかりませんが、JVMが乱暴になります。
Zee

1
@Zee WiresharkでFINとして表示されるポートを閉じることと、そうではない接続を中止することには違いがあります。
ローン侯爵、2015年

2

Tomcatソースコード JVMソースを確認しましたか?それはあなたにもっと助けを与えるかもしれません。

あなたの一般的な考え方は良いと思います。ConnectExceptionあなたが接続できなかったシナリオでは、私は期待します。上記はクライアント主導のように見えます。


3
はい、チェックしました。Tomcatのソースには、文の順列は含まれていませんでした。
エランメダン2010年

1
いいえ、彼はTomcatソース JVMソースをチェックしていません。
Stephen C

または、JVMソースをチェックしたが、すべてをチェックしていない。
スティーブンC

1
@Ehrann-メッセージ文字列は、おそらくネイティブソースにあります。ただし、イベントログも確認する必要があります。IMO、後者はより有益である可能性があります。
スティーブンC

6
このメッセージ文字列は、実際にはオペレーティングシステムからのものです。
ローン侯爵

2

単純なクライアントサーバープログラムを使用してこのエラーが発生する場合、入力ストリームまたは出力ストリームが閉じられていない(または早く閉じられている)ことが問題です。


2
いいえ、そうではありません。これはソケットリークを引き起こし、最終的にFDの枯渇を引き起こします。
ローン侯爵、2015年

0

私は同じ問題に直面していました。
一般に、この種のエラーは、クライアントが接続を閉じたために発生し、サーバーはそのクライアントでまだ書き込みを試みています。
したがって、サーバーがその出力ストリームを完了するまで、クライアントの接続が開いていることを確認してください。
そしてもう1つ、入力ストリームと出力ストリーム閉じるのを忘れないでください

お役に立てれば。
それでも問題が解決しない場合は、ここで問題を詳しく説明してください。


3
@BhavinChhatrolaいいえ、不正解です。説明されている状況では、問題のエラーではなく、「ピアによる接続リセット」が生成されます。
ローン伯爵の

0

このエラーは、SoapUIクライアントでSOAPサービスをテストしているときに発生しました。基本的に、非常に大きなメッセージ(> 500kb)を取得しようとしていて、SoapUIがタイムアウトによって接続を閉じました。

SoapUIで次の場所に移動します。

ファイル->設定-ソケットタイムアウト(ミリ秒)

...そして180000(3分)などの大きな値を入力すると、ファイルは実際には非常に大きいため、これは問題の完全な修正にはなりませんが、少なくとも応答はあります。


0

別のクライアントの閉じられた接続

私の場合、エラーは:

java.net.SocketException: Software caused connection abort: recv failed

H2データベースにアクセスするJavaアプリケーションのデバッグ中にEclipseで受信されました。エラーの原因は、最初にSQuirreLを使用してデータベースを開き、整合性を手動でチェックしたことです。フラグを使用して同じDB(つまりAUTO_SERVER=TRUE)への複数の接続を有効にしたので、JavaからDBへの接続に問題はありませんでした。

エラーは、しばらくすると-それは長いJavaプロセスです-SQuirreLを閉じてリソースを解放することを決めたときに表示されました。SQuirreLがDBサーバーインスタンスを「所有している」ものであり、SQuirreL接続でシャットダウンされたように見えます。

Javaアプリケーションを再起動しても、エラーは発生しませんでした。

設定

  • Windows 7
  • Eclipseケプラー
  • SQuirreL 3.6
  • org.h2.Driverバージョン1.4.192

0

私の場合、クライアントとサーバー側を開発しましたが、例外があります:

原因:引数のマーシャリングエラー。ネストされた例外は次のとおりです:java.net.SocketException:ソフトウェアが接続を中止しました:ソケット書き込みエラー

クライアントとサーバーのクラスが異なる場合。サーバーのクラス(インターフェイス)をクライアントにダウンロードしません。同じファイルをプロジェクトに追加します。しかし、パスはまったく同じでなければなりません。たとえば、サーバープロジェクトでは、いくつかのserviceInterfaceと実装を含むjava \ rmi \ servicesパッケージがあり、クライアントプロジェクトで同じパッケージを作成する必要があります。たとえば、java / rmi / server / servicesで変更すると、上記の例外が発生します。クライアントとサーバー間でインターフェースのバージョンが異なる場合も同じ例外(空の行が誤って追加された場合でも...バージョンを確認するためにrmiがクラスのハッシュのようなものを作成すると思います...わからない...もし可能なら助けて ...


-1

私のサーバーは2日のパスでこの例外をスローしていましたが、次のコマンドで切断機能を移動することで解決しました。

outputStream.close();
inputStream.close();
Client.close();

リストスレッドの最後まで。それが誰かを助けるなら。


-1

以下で説明する状況では、クライアント側がそのような例外をスローします。

サーバーはクライアント証明書を認証するように求められますが、クライアントは拡張キー使用法がクライアント認証をサポートしない証明書を提供するため、サーバーはクライアントの証明書を受け入れず、接続を閉じます。


この答えは間違っています。SSLExceptionがスローされることを記述した場合。
ジェームズK.ポーク大統領

実際には、現在の質問と同じようにSocketExceptionがスローされます。私はテストしました
xiaoming

-1

sslクライアント側は、以下の状況(テスト済み)でこのような例外をスローします。

サーバーはクライアント証明書を認証するように求められますが、クライアントは拡張キー使用法がクライアント認証をサポートしない証明書を提供します。


-3

残りのAPI呼び出しをモックしているときに、wireMockで同じ問題に直面していました。以前は、次のようにサーバーを定義していました。

WireMockServer wireMockServer = null;

ただし、次のように定義する必要があります。

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

これはNullPointerException、この問題ではなくを引き起こします。
ローン侯爵
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.