java.net.SocketException: Connection reset by peer: socket write error 提供文件时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25611741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:46:37  来源:igfitidea点击:

java.net.SocketException: Connection reset by peer: socket write error When serving a file

javasocketssocketexception

提问by Charles-Eugene Loubao

I am trying to implement an HTTP Server using Sockets. If the Client (For example a browser) requests a directory the server displays a list of available files. The problem arises when the client is requesting a file. I get the following error:

我正在尝试使用套接字实现 HTTP 服务器。如果客户端(例如浏览器)请求目录,则服务器会显示可用文件列表。当客户端请求文件时会出现问题。我收到以下错误:

java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at cf.charly1811.java.web.RequestHandler.writeFile(RequestHandler.java:152)
at cf.charly1811.java.web.RequestHandler.processRequest(RequestHandler.java:139)
at cf.charly1811.java.web.RequestHandler.handleRequest(RequestHandler.java:110)
at cf.charly1811.java.web.RequestHandler.run(RequestHandler.java:86)
at java.lang.Thread.run(Thread.java:745)

The stacktrace shows that the problem is coming from the writeFile()methods:

堆栈跟踪显示问题来自以下writeFile()方法:

private void writeFile(File request) throws IOException 
{
    InputStream byteReader = new BufferedInputStream(new FileInputStream(request));
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = byteReader.read(buffer)) != -1) 
    {
        outputStream.write(buffer, 0, bytesRead);
    }
    byteReader.close();
}

But I can't figure out what's wrong. Can you help me?

但我无法弄清楚出了什么问题。你能帮助我吗?

EDIT

编辑

Thanks everyone for your answers. After I read your answers I understood that the problem was that the Socket when an error occured. Here's was my wrong code:

谢谢大家的回答。阅读您的答案后,我明白问题出在发生错误时的 Socket。这是我的错误代码:

// Method to process a single request
handleRequest() throw IOException
{
    // process here
    // if the client request a file
    writeFile();
    // close socket when the request is processed
}

// The method is called
public run()
{
    try{
        // If an error occurs the try/catch won't be called because it is implemented outside the loop. So when an IOException occurs, the loop just stop and exit the program
        while(true)
        {
            handleRequest();
        }
    }
    catch(IOException e) {
        // Handle exception here
    }
}

And my new code was looking like this:

我的新代码如下所示:

// Method to process a single request
handleRequest()
{
   try {
        // process here
        // if the client request a file
        writeFile();
        // close socket when the request is processed
    }
    // If this exception occurs the catch() method will be called
    catch(IOException e)
    {
        // handle exception here
    }
}

// The method is called
public run()
{
    while(true)
        {
            handleRequest();
        }
    }
}

采纳答案by bond

It is possible for the TCP socket to be "closing" and your code to not have yet been notified.

TCP 套接字可能“关闭”并且您的代码尚未收到通知。

Here is a animation for the life cycle. http://tcp.cs.st-andrews.ac.uk/index.shtml?page=connection_lifecycle

这是生命周期的动画。http://tcp.cs.st-andrews.ac.uk/index.shtml?page=connection_lifecycle

Basically, the connection was closed by the client. You already have throws IOExceptionand SocketExceptionextends IOException. This is working just fine. You just need to properly handle IOExceptionbecause it is a normal part of the api.

基本上,连接已被客户端关闭。您已经拥有throws IOExceptionSocketException扩展了IOException. 这工作得很好。您只需要正确处理,IOException因为它是 api 的正常部分。

EDIT: The RSTpacket occurs when a packet is received on a socket which does not exist or was closed. There is no difference to your application. Depending on the implementation the resetstate may stick and closedwill never officially occur.

编辑:RST当在不存在或已关闭的套接字上接收到数据包时,会发生数据包。您的应用程序没有区别。根据实施情况,reset状态可能会坚持下去,并且closed永远不会正式发生。

回答by user207421

This problem is usually caused by writing to a connection that had already been closed by the peer. In this case it could indicate that the user cancelled the download for example.

此问题通常是由写入已被对等方关闭的连接引起的。例如,在这种情况下,它可能表明用户取消了下载。