Java.Net.SocketException を修正: Java の壊れたパイプ エラー

Mehvish Ashiq 2023年10月12日
Java.Net.SocketException を修正: Java の壊れたパイプ エラー

このチュートリアルでは、Java プログラミングを使用して java.net.SocketException: Broken pipe エラーを示し、考えられる原因と解決策を強調します。

エラーの説明、理由、および解決策

その理由を掘り下げて解決策を見つける前に、エラーを知ることが重要です。 それでは、動的バッファ サイズをソケット ストリームに送信する必要があるエラーのデモから始めましょう。これは問題なく動作します。

int myBufferSize = 18 * 1024; より大きいサイズの複数のバッファを送信しようとすると、エラーが発生します。 (参考値です)。

コード例:

byte[] bs = new byte[myBufferSize];
while (...) {
  fileInputStream.read(bs);
  byte[] bufferToSend = new byte[sizeBuffer];
  DataOutputStream dataOutputStream = new DataOutputStream(client.getoutputStream());
  dataOutputStream.writeInt(bufferToSend.length);
  dataOutputStream.write(bufferToSend);
  dataOutputStream.flush();
}

エラーの説明:

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)

壊れたパイプは何を意味しますか? 壊れたパイプは、パイプの反対側のマシンが終了している間に、1つのマシンがパイプとの間でデータの書き込み/読み取りを試みていることを意味します。

接続が終了したため、データを転送するには新しい接続を確立する必要があります。 そうしないと、データ転送が停止します。

Java には特に BrokenPipeException がないことに注意してください。

この種のエラーは、IOExceptionSocketException などのさまざまな例外に明らかにラップされます。 私たちの場合、壊れたパイプは SocketException でラップされています。

この問題が発生する理由と、これを解決する方法を教えてください。 一般的な原因のいくつかを次のセクションに示します。

Java での java.net.SocketException: Broken pipe エラーの理由

次のいずれかが発生した場合、このエラーに直面する可能性があります。

  1. このエラーは、複数のクライアントが 1つのサーバーに接続し、応答が完全に提供/転送される前に複数のクライアントが接続を閉じると断続的に発生します。
  2. ほとんどの場合、相手側ですでに閉じられている接続に書き込むときに発生します。
  3. ピアがデータ全体を読み取らずに接続を閉じたときにも発生する可能性があり、ピア側で保留中です。 別のケースでは、ピアは接続を適切に閉じる代わりに、リセットするために意図的なアクションを実行します。
  4. ページが完全に読み込まれる前にユーザーがブラウザーを閉じた場合、サーバーのクライアント セッションが予期せず切断されます。
  5. または、現在のページが完全にロードされる前に、ユーザーが別のページに移動します。
  6. 読み込み中にインターネット接続が失敗した場合にも、このエラーが発生します。
  7. このエラーのもう 1つの状況は、ブラウザがリクエスト接続の接続をタイムアウトした場合です。 ほとんどの場合、大きなリソースをアップロードしようとしたときに発生します。

Java で java.net.SocketException: Broken pipe エラーを根絶するために考えられる解決策

クライアント/サーバー プログラミングの実行中にこのエラーを排除するために、さまざまな方法を使用できます。 開発者に知らせるために、根本原因を無視または処理しますか?

  1. 通常、サーバー アプリケーションでこの種のエラーを処理することは、サーバーが他のクライアントの影響を受けないようにするために必要です。 はい、データ/応答が完全に転送される前にクライアントが既に切断されているため、サポート担当者として無視できます。

  2. 巨大なリソースのアップロード中にエラーが発生した場合は、長いリクエスト タイムアウトで API を正常に動作させる必要があります。

  3. 場合によっては、ポート スキャナーが接続を開いてすぐに閉じることによって、その役割を果たします。 私たちのサーバーは、接続の失敗を処理するようにプログラムされていません。

    これは、この状況に対応したコーディングを行っていないためです。 ここでは、この状況を処理するために try-catch を使用する必要があります。

  4. 壊れたパイプの問題は、コードではなく、反対側にあります。 おそらく、もう一方の端 (クライアントまたはサーバーの可能性があります) は、長さの単語のプロトコルを理解していません。

    たとえば、それを正しく実装していません。 このコード (エラーのデモンストレーションで提供) に似たものであれば、そうではありません。

    read() によって返された応答は無視します。 さらに、バッファがいっぱいになったとします。 それを行うことは指定されておらず、1 バイトの送信/転送のみが指定されています。

  5. 別の解決策は、入出力例外が発生したコードをチェックし、それを try-catch ブロックでラップして IOException をキャッチすることです。 次に、この半有効なシナリオをどのように処理するかを決定するのは私たち次第です。

    このケースは、破損したパイプが IOException にラップされている場合にのみ適用されることに注意してください。

著者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

関連記事 - Java Exception