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
がないことに注意してください。
この種のエラーは、IOException
や SocketException
などのさまざまな例外に明らかにラップされます。 私たちの場合、壊れたパイプは SocketException
でラップされています。
この問題が発生する理由と、これを解決する方法を教えてください。 一般的な原因のいくつかを次のセクションに示します。
Java での java.net.SocketException: Broken pipe
エラーの理由
次のいずれかが発生した場合、このエラーに直面する可能性があります。
- このエラーは、複数のクライアントが 1つのサーバーに接続し、応答が完全に提供/転送される前に複数のクライアントが接続を閉じると断続的に発生します。
- ほとんどの場合、相手側ですでに閉じられている接続に書き込むときに発生します。
- ピアがデータ全体を読み取らずに接続を閉じたときにも発生する可能性があり、ピア側で保留中です。 別のケースでは、ピアは接続を適切に閉じる代わりに、リセットするために意図的なアクションを実行します。
- ページが完全に読み込まれる前にユーザーがブラウザーを閉じた場合、サーバーのクライアント セッションが予期せず切断されます。
- または、現在のページが完全にロードされる前に、ユーザーが別のページに移動します。
- 読み込み中にインターネット接続が失敗した場合にも、このエラーが発生します。
- このエラーのもう 1つの状況は、ブラウザがリクエスト接続の接続をタイムアウトした場合です。 ほとんどの場合、大きなリソースをアップロードしようとしたときに発生します。
Java で java.net.SocketException: Broken pipe
エラーを根絶するために考えられる解決策
クライアント/サーバー プログラミングの実行中にこのエラーを排除するために、さまざまな方法を使用できます。 開発者に知らせるために、根本原因を無視または処理しますか?
-
通常、サーバー アプリケーションでこの種のエラーを処理することは、サーバーが他のクライアントの影響を受けないようにするために必要です。 はい、データ/応答が完全に転送される前にクライアントが既に切断されているため、サポート担当者として無視できます。
-
巨大なリソースのアップロード中にエラーが発生した場合は、長いリクエスト タイムアウトで API を正常に動作させる必要があります。
-
場合によっては、ポート スキャナーが接続を開いてすぐに閉じることによって、その役割を果たします。 私たちのサーバーは、接続の失敗を処理するようにプログラムされていません。
これは、この状況に対応したコーディングを行っていないためです。 ここでは、この状況を処理するために
try-catch
を使用する必要があります。 -
壊れたパイプの問題は、コードではなく、反対側にあります。 おそらく、もう一方の端 (クライアントまたはサーバーの可能性があります) は、長さの単語のプロトコルを理解していません。
たとえば、それを正しく実装していません。 このコード (エラーのデモンストレーションで提供) に似たものであれば、そうではありません。
read()
によって返された応答は無視します。 さらに、バッファがいっぱいになったとします。 それを行うことは指定されておらず、1 バイトの送信/転送のみが指定されています。 -
別の解決策は、入出力例外が発生したコードをチェックし、それを
try-catch
ブロックでラップしてIOException
をキャッチすることです。 次に、この半有効なシナリオをどのように処理するかを決定するのは私たち次第です。このケースは、破損したパイプが
IOException
にラップされている場合にのみ適用されることに注意してください。