如何解决“Connection reset by peer: socket write error”错误?

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

如何解决这个问题?


客户端是什么?如果由您编写,它如何读取响应? - Serge
我通过jQuery Ajax函数向该Servlet发出了请求。 - Babu R
我在 div 的 onclick() 中下载一个文件。 - Babu R
@BabuR,你解决了这个问题吗?我在尝试通过servlet传输视频时也遇到了同样的问题。 - ishan
显示剩余2条评论
5个回答

14

我遇到了与此相同的异常问题,实际上问题出在重新协商过程中。事实上,在我的情况下,当服务器尝试更改密码组时,我的客户端关闭了连接。经过深入挖掘,发现在jdk 1.6更新22版中默认禁用了重协商过程。如果您的安全约束可以承受,请尝试通过将sun.security.ssl.allowUnsafeRenegotiation系统属性设置为true来启用不安全的重协商。以下是一些关于该过程的信息:

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

此外,还有一个详细介绍此问题的优秀文章,用(我认为)易于理解的语言编写。


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

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

4
虽然你关于向流中写入正确长度的字节是正确的,但这不应该引起“连接被对方重置”的错误。客户端应该只是在正确数据后看到一些垃圾数据。 - Deepak Bala
感谢您的回复。我尝试使用您的代码,但它显示java.lang.IndexOutOfBoundsException错误。 - Babu R
我解决了索引越界的问题,但是我之前提出的同样的问题仍然存在: - Babu R
1
java.net.SocketException: 连接被对等方重置:套接字写入错误 在org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:388) 在org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462) 在org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366) 在org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:413) 在org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:401) 在org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91) - Babu R

0

我遇到了一个与此类似的问题:

在刷新时出现异常

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

response.setHeader("Content-Encoding", "gzip");

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

因此,浏览器关闭了连接。


0

正确的解决方法是关闭连接并忘记客户端。当您仍在向其写入数据时,客户端已关闭连接,因此他不想再与您有任何关系,这就是结果,不是吗?


请问您如何关闭连接? - Babu R
@BabuR 关闭输出流。 - user207421

0

看起来你的问题可能出现在

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

在程序中,如果不推进偏移量(在调用中始终为0),它可能会陷入无限循环。请尝试

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接