簡體   English   中英

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

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

我正在嘗試使用套接字實現 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)

堆棧跟蹤顯示問題來自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();
}

但我無法弄清楚出了什么問題。 你能幫助我嗎?

編輯

謝謝大家的回答。 閱讀您的答案后,我明白問題出在發生錯誤時的 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
    }
}

我的新代碼如下所示:

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

TCP 套接字可能“關閉”並且您的代碼尚未收到通知。

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

基本上,連接已被客戶端關閉。 您已經有throws IOExceptionSocketException extends IOException 這工作得很好。 您只需要正確處理IOException因為它是 api 的正常部分。

編輯: RST數據包在不存在或已關閉的套接字上接收到數據包時發生。 您的應用程序沒有區別。 根據實現, reset狀態可能會保持不變,並且永遠不會正式發生closed

此問題通常是由寫入已被對等方關閉的連接引起的。 例如,在這種情況下,它可能表明用戶取消了下載。

我面臨這個問題,但解決方法很簡單。 我在 1024 字節緩沖區中寫入 1 MB 文件導致此問題。 了解修復前后的參考代碼。

異常代碼

DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        
        while (fis.read(buffer) > 0) {
            dos.write(buffer);
        }
    

修復后:

DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[102400];
        
        while (fis.read(buffer) > 0) {
            dos.write(buffer);
        }

    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM