21

当我从服务器读取文件内容时,它返回以下错误消息:

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

我的servlet程序是

 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();

如何解决这个问题?

4

5 回答 5

14

我有同样的例外,在我的情况下,问题出在重新谈判过程中。事实上,当服务器尝试更改密码套件时,我的客户端关闭了连接。挖掘后看来,在 jdk 1.6 更新 22重新协商过程中默认禁用。如果您的安全约束可以解决此问题,请尝试通过将sun.security.ssl.allowUnsafeRenegotiation系统属性设置为 来启用不安全的重新协商true。以下是有关该过程的一些信息:

会话重新协商是 SSL 协议中的一种机制,它允许客户端或服务器在正在进行的 SSL 通信期间触发新的 SSL 握手。重新协商最初被设计为一种提高正在进行的 SSL 通道安全性的机制,通过触发用于保护该通道的加密密钥的更新。但是,现代密码算法不需要这种安全措施。此外,当客户端尝试访问服务器上特定的受保护资源时,服务器可以使用重新协商来请求客户端证书(以执行客户端身份验证)。

此外,还有一篇关于这个问题详细文章,并以(恕我直言)可理解的语言编写。

于 2013-07-15T14:15:06.227 回答
3

客户端(浏览器)已关闭套接字。

您的代码中的错误:

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 );
}

这不是你的问题,但这是我的答案...... ;-)

于 2012-10-20T08:10:07.903 回答
0

“解决”它的正确方法是关闭连接并忘记客户端。客户端已经关闭了连接,而你还在写它,所以他不想认识你,就是这样,不是吗?

于 2012-10-20T09:11:06.203 回答
0

看来您的问题可能出现在

while(in.read(outputByte,0,4096)!=-1){

它可能会因为不推进偏移量而进入无限循环(在调用中始终为 0)。尝试

while(in.read(outputByte)!=-1){

默认情况下,它将尝试将 outputByte.length 读入byte[]. 这样您就不必担心偏移量。参见FileInputStrem 的读取方法

于 2012-10-20T09:27:08.413 回答
0

我有同样的问题,但差异很小:

刷新时引发异常

这是一个不同的stackoverflow 问题。简要说明是错误的响应标头设置:

response.setHeader("内容编码", "gzip");

尽管响应数据内容未压缩。

所以连接被浏览器关闭了。

于 2016-05-02T14:24:55.447 回答