java - HTTP 请求处理程序连接重置错误

标签 java multithreading http libgdx

我正在编写一个简单的 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 header ,我目前让程序在每次完成响应后关闭连接。

最佳答案

我在做了一些数据包嗅探后发现了这个设计的问题。在客户端确认接收到数据包之前,服务器发送的数据包太多、速度太快。结果,服务器向客户端发送 TCP 重置。当客户端尝试重新建立连接时,服务器拒绝接受连接,因为它已经退出了发送文件的语句并关闭了套接字连接。客户端继续处理其他文件,并将尝试再次请求不完整的文件。服务器随后会再次发送文件,但客户端将无法像往常一样及时确认。此时,客户端只是放弃了该文件。

由于我的设计一次只能处理一个请求,并且无法从它可能停止的地方接起,修改我的代码以将文件分成 block 并在 hibernate 一毫秒后一次发送一个 block .

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

关于java - HTTP 请求处理程序连接重置错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48277549/

相关文章:

Java代理拦截请求

java - Java 中的 HttpServer 流请求正文

java - 如何使用java读取多个JSON文件并将其写入单个JSON文件

java - 微软图: Daemon App Accesses Shared Calendars of only One User

multithreading - Clojure并行计算数组

java - RejectedExecutionException 后调用线程不会停止

http - PROC HTTP 等效于 curl 选项 --insecure/-k

java - NetBeans 中的警告 : Skipping entry because it is not an absolute URI. GlassFish

java - 为什么 javac 不能为用作参数的函数推断泛型类型参数?

c# - ProgressBar 在阻塞的 UI 线程中更新