簡體   English   中英

HTTP請求處理程序連接重置錯誤

[英]HTTP Request Handler Connection Reset Error

我正在編寫一個簡單的HTTP請求處理程序,但在文件傳輸到客戶端瀏覽器時一直隨機遇到連接重置錯誤。

由於我的程序很大,因此我將簡化以下代碼:

public class HTTPRequestHandler implements Runnable {
    private Queue<HTTPRequest> requests;
    private volatile boolean flag;
    ...
    public void run() {
        flag = true;
        while (flag) {
            HTTPRequest request = null;
            synchronized(this) {
                if (requests.size > 0) {
                     request = requests.removeFirst();
                }
            }

            if (request != null) {
                handleRequest(request);
            }
        }
    }
    ...
    private void handleRequest(HTTPRequest request) {
        ...
        try {
            // Send HTTP Header
            request.getSocket().getOutputStream().write(message.getHeader().getBytes());

            // Send HTTP Message Body
            Object messageBody = message.getMessageBody();
            if (messageBody != null && messageBody.getClass() == File.class) {
                Files.copy(((File)messageBody).toPath(), request.getSocket().getOutputStream());
                request.getSocket().getOutputStream().flush();
            } else if (messageBody != null) {
                ...
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ...
    }

我能夠使這部分大部分時間(並非總是)在本地計算機上的各種瀏覽器上工作,但在遠程計算機上卻根本無法使用。 它主要針對大文件隨機發生,有時也針對小文件隨機發生。

至於HTTP標頭,我目前讓程序在每個完整響應后關閉連接。

經過一些數據包嗅探之后,我發現了這種設計的問題。 服務器發送太多數據包的速度太快,客戶端無法確認收到它們。 結果,服務器將TCP重置發送給客戶端。 當客戶端嘗試重新建立連接時,服務器拒絕接受該連接,因為它已經退出了發送文件的語句並關閉了套接字連接。 客戶端繼續處理其他文件,並將嘗試再次請求不完整的文件。 然后,服務器將再次發送文件,但是客戶端將無法像往常一樣及時確認。 此時,客戶端只是放棄了該文件。

由於我的設計一次只能處理一個請求,並且無法從可能中斷的地方進行處理,因此請修改我的代碼以將文件分成多個塊,並在休眠一毫秒后一次發送一個塊。

if (messageBody != null && messageBody.getClass() == File.class) {
    InputStream fileStream = new FileInputStream((File)messageBody);
    byte[] buffer = new byte[8 * 1460]; // Maximum TCP packet size
    int bytesRead;
    while ((bytesRead = fileStream.read(buffer)) != -1) {
        request.getSocket().getOutputStream().write(buffer, 0, bytesRead);
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    fileStream.close();
}

暫無
暫無

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

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