【问题标题】:Close a socket created in handle of HttpRequestHandler关闭在 HttpRequestHandler 的句柄中创建的套接字
【发布时间】:2015-12-11 16:41:24
【问题描述】:

我正在使用 apache 的 HttpCore 实现代理。
这是我的 HttpRequestHandler,它基于反向代理示例,来自 apache link

static class ProxyHandler implements HttpRequestHandler  {

    private final HttpHost target;
private final HttpProcessor httpproc;
private final HttpRequestExecutor httpexecutor;
private final ConnectionReuseStrategy connStrategy;
private SocketFactory sf;
public ProxyHandler(
        final HttpHost target,
        final HttpProcessor httpproc,
        final HttpRequestExecutor httpexecutor,
        SocketFactory sf) {
    super();
    this.target = target;
    this.httpproc = httpproc;
    this.httpexecutor = httpexecutor;
    this.sf = sf;
    this.connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
}

public void handle(
        final HttpRequest request,
        final HttpResponse response,
        final HttpContext context) throws HttpException, IOException {


    final int bufsize = 8 * 1024;
    URI uri = null;
    try {
        uri = new URI(request.getRequestLine().getUri());
    } catch (URISyntaxException e) {
        e.printStackTrace();
        return;
    }
    String domain = uri.getHost();
    HttpHost host = new HttpHost(domain, 80);
    System.out.println("host "+domain);

    DefaultBHttpClientConnection outconn = (DefaultBHttpClientConnection) context.getAttribute(HTTP_OUT_CONN);
    final Socket outsocket = sf.createSocket(host.getHostName(), this.target.getPort());
    outconn = new DefaultBHttpClientConnection(bufsize);
    outconn.bind(outsocket);
    System.out.println("My Outgoing connection to " + outsocket.getInetAddress());

    context.setAttribute(HTTP_OUT_CONN, outconn);
    final HttpClientConnection conn = (HttpClientConnection) context.getAttribute(
            HTTP_OUT_CONN);

    context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn);
    context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);

    System.out.println(">> Request URI: " + request.getRequestLine().getUri());

    // Remove hop-by-hop headers
    request.removeHeaders(HTTP.CONTENT_LEN);
    request.removeHeaders(HTTP.TRANSFER_ENCODING);
    request.removeHeaders(HTTP.CONN_DIRECTIVE);
    request.removeHeaders("Keep-Alive");
    request.removeHeaders("Proxy-Authenticate");
    request.removeHeaders("TE");
    request.removeHeaders("Trailers");
    request.removeHeaders("Upgrade");

    this.httpexecutor.preProcess(request, this.httpproc, context);
    final HttpResponse targetResponse = this.httpexecutor.execute(request, conn, context);
    this.httpexecutor.postProcess(response, this.httpproc, context);

    // Remove hop-by-hop headers
    targetResponse.removeHeaders(HTTP.CONTENT_LEN);
    targetResponse.removeHeaders(HTTP.TRANSFER_ENCODING);
    targetResponse.removeHeaders(HTTP.CONN_DIRECTIVE);
    targetResponse.removeHeaders("Keep-Alive");
    targetResponse.removeHeaders("TE");
    targetResponse.removeHeaders("Trailers");
    targetResponse.removeHeaders("Upgrade");

    response.setStatusLine(targetResponse.getStatusLine());
    response.setHeaders(targetResponse.getAllHeaders());
    response.setEntity(targetResponse.getEntity());

    System.out.println("<< Response: " + response.getStatusLine());

    final boolean keepalive = this.connStrategy.keepAlive(response, context);
    context.setAttribute(HTTP_CONN_KEEPALIVE, new Boolean(keepalive));
    outsocket.close();
}

}

我已经更改了处理函数并在其中创建, DefaultBHttpClientConnection outconn 基于请求 URI 中的主机。
如您所见,我使用 SocketFactory 创建了一个新套接字 (outsocket)。 问题我不知道如何关闭套接字。
我尝试在 handle() 结束时关闭它,但随后我会开始接收

I/O 错误:套接字关闭

代理停止工作。
调用 httpservice.handleRequest() 的线程与链接中示例中的线程相同(如果需要,我可以发布它,我没有导致它在问题中占用空间)。

【问题讨论】:

    标签: java apache sockets http


    【解决方案1】:

    我已经解决了这个问题。 就是这条线:

    outconn = new DefaultBHttpClientConnection(bufsize);
    

    在处理程序内部。

    所以每次调用处理程序时,它都会创建一个新的 outconn 。 以及在调用之前设置的那个:

    httpservice.handleRequest(this.inconn, context);
    

    即使它被关闭,它也不会关闭套接字,因为它绑定到 outconn 的不同副本。

    【讨论】:

      【解决方案2】:

      如果你正在做一个代理,你应该关闭连接的唯一一次是如果你在一侧得到一个 IOException ,它会关闭那一半的对话;到那时,结束对话的另一方是安全的

      【讨论】:

      • 由于客户端请求,代理创建到服务器的套接字,在代理从服务器获得响应后,它必须关闭它专门为该服务器打开的套接字
      猜你喜欢
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多