能够保持活动的HTTP服务器 [英] HTTP server capable of Keep-Alive

查看:108
本文介绍了能够保持活动的HTTP服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用Java创建一个能够提供保持连接的http服务器。我正在使用com.sun.net.httpserver.HttpServer类。

I'm trying to create a http server in Java which is capable of providing keep-alive connections. I'm using the com.sun.net.httpserver.HttpServer class.

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class httpHandler implements HttpHandler {

private String resp = "<?xml version='1.0'?><root-node></root-node>";

private OutputStream os = null;

public void handle(HttpExchange t) throws IOException {
    System.out.println("Handling message...");
    java.io.InputStream is = t.getRequestBody();

    System.out.println("Got request body. Reading request body...");
    byte[] b = new byte[500];
    is.read(b);
    System.out.println("This is the request: " + new String(b));

    String response = resp;
    Headers header = t.getResponseHeaders();
    header.add("Connection", "Keep-Alive");
    header.add("Keep-Alive", "timeout=14 max=100");
    header.add("Content-Type", "application/soap+xml");
    t.sendResponseHeaders(200, response.length());

    if(os == null) {
        os = t.getResponseBody();
    }

    os.write(response.getBytes());

    System.out.println("Done with exchange. Closing connection");
    os.close();
}

public static void main(String[] args) {
    HttpServer server = null;
    try {
        server = HttpServer.create(new InetSocketAddress(8080), 5);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    server.createContext("/", new httpHandler());
    server.setExecutor(null); // creates a default executor
    System.out.println("Starting server...");
    server.start();
}
}

客户端不会关闭连接。服务器似乎在交换发生后直接关闭它。我尝试删除os.close行,但服务器不会回复第二个请求。但它也没有关闭它。我有一种感觉它涉及在服务器对象的主代码中做一些事情,但我不知道是什么。 Google的收入也不高。

The client does not close the connection. The server seems to close it instead directly after the exchange has occurred. I tried deleting the os.close line but then the server will not reply to the second request. But it doesn't close it either. I have a feeling it involves doing something in the main code with the server object but I have no idea what. Google isn't turning up much either.

这里有人有任何想法吗?任何帮助将非常感激。

Anyone here got any ideas? Any help would be much appreciated.

推荐答案

看起来问题是你没有从请求中排出所有数据。你应该继续做 is.read(),直到它返回-1,然后关闭它。

It looks like the problem is you didn't drain all data from request. You should keep doing is.read() until it returns -1, then close it.

既然你没有不要消耗请求,还剩下字节。服务器不能简单地跳转到下一个请求;它不像磁盘,更像是磁带。服务器必须从当前请求中读取(并丢弃)所有数据,然后才能到达下一个请求。

Since you didn't drain the request, there are still bytes left. The server cannot simply "jump" to the next request; it's not like a disk, more like a tape. Server has to read(and discard) all data from current request, before the it can reach the next request.

没有限制,这可以用来攻击服务器;所以服务器只会尝试排出一个限制,默认为64K。您可能正在收到大于64K的请求。

Without a limit this can be used to attack the server; so the server would only attempt to drain up to a limit, which is 64K by default. You are probably receiving a request bigger than 64K.

通常,处理程序应首先读取整个请求。否则它如何知道如何提供请求?

Usually the handler should read the entire request first. Otherwise how does it know how to serve the request?

更严重的是,如果请求没有先耗尽,可能会发生死锁。客户端通常很简单:它们写入请求,然后读取响应。如果服务器在读取所有请求之前写入响应,则客户端仍可以写入请求。两人都在互相写信,但两人都没有读书。如果缓冲区已满,那么我们处于死锁状态,两者都在写入时被阻止。注意write()没有超时!

More seriously, if the request is not drained first, deadlock can happen. Clients are typically simple: they writes the request, then read the response. If the server writes the response before it reads all the request, the client could be still writing the request. Both are writing to each other but neither is reading. If buffers are full then we are in a deadlock, both are blocked on write. Note there's no timeout for write()!

这篇关于能够保持活动的HTTP服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆