サーバーからファイルコンテンツを読み取ると、次のエラーメッセージが返されます。
Caused by: Java.net.SocketException: Connection reset by peer: socket write error
at Java.net.SocketOutputStream.socketWrite0(Native Method)
at Java.net.SocketOutputStream.socketWrite(Unknown Source)
at Java.net.SocketOutputStream.write(Unknown Source)
at org.Apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.Java:215)
at org.Apache.Tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.Java:462)
at org.Apache.Tomcat.util.buf.ByteChunk.append(ByteChunk.Java:366)
at org.Apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.Java:240)
at org.Apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.Java:119)
at org.Apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.Java:192)
at org.Apache.coyote.Response.doWrite(Response.Java:504)
at org.Apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.Java:383)
... 28 more
私のサーブレットプログラムは
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename="+filename);
FileInputStream in = new FileInputStream(new File(filepath));
ServletOutputStream output=response.getOutputStream();
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);//error indicates in this line
}
in.close();
output.flush();
output.close();
この問題を解決するには?
同じ例外がありましたが、私の場合、問題は再交渉のプロセスにありました。実際、サーバーが暗号スイートを変更しようとしたときに、クライアントが接続を閉じました。掘り下げた後、jdk 1.6 update 22では 再ネゴシエーションプロセスはデフォルトで無効になっています のように見えます。セキュリティ上の制約によりこれを実現できる場合は、Sun.security.ssl.allowUnsafeRenegotiation
システムプロパティをtrue
に。プロセスに関する情報を次に示します。
セッション再ネゴシエーションは、進行中のSSL通信中にクライアントまたはサーバーが新しいSSLハンドシェイクをトリガーできるようにするSSLプロトコル内のメカニズムです。再ネゴシエーションは当初、進行中のSSLチャネルのセキュリティを強化するメカニズムとして設計され、そのチャネルを保護するために使用される暗号キーの更新をトリガーします。ただし、このセキュリティ対策は、最新の暗号化アルゴリズムでは必要ありません。さらに、クライアントがサーバー上の特定の保護されたリソースにアクセスしようとするときに、クライアント認証を実行するためにサーバーが再ネゴシエーションを使用してクライアント証明書を要求できます。
さらに、この問題について excellent post があり、(IMHO)理解可能な言語で書かれています。
ソケットはクライアント(ブラウザー)によって閉じられました。
コードのバグ:
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);
}
最後のパケットの読み取り、その後の書き込みの長さは4096未満になる可能性があるため、次のことをお勧めします。
byte[] outputByte=new byte[4096];
int len;
while(( len = in.read(outputByte, 0, 4096 )) > 0 ) {
output.write( outputByte, 0, len );
}
それはあなたの質問ではありませんが、私の答えです... ;-)
私は同じ問題に小さな違いがありました:
フラッシュ時に例外が発生しました
それは異なる stackoverflow issue です。簡単な説明は、間違った応答ヘッダー設定でした:
response.setHeader( "Content-Encoding"、 "gzip");
圧縮されていない応答データコンテンツにもかかわらず。
そのため、ブラウザーによって接続が閉じられました。
「解決」する正しい方法は、接続を閉じてクライアントを忘れることです。クライアントは、あなたがまだ書き込みをしている間に接続を閉じたので、彼はあなたを知りたくないので、そうですよね?
問題が発生しているようです
while(in.read(outputByte,0,4096)!=-1){
オフセットを進めないために無限ループに入る可能性があります(呼び出しでは常に0です)。試して
while(in.read(outputByte)!=-1){
デフォルトでは、outputByte.lengthまでをbyte[]
に読み取ろうとします。このように、オフセットを心配する必要はありません。 FileInputStremの読み取りメソッド を参照してください