0

我正在调试我正在编写的netty代理的问题,我注意到即使我跳过“代理”方面并实现一个简单的http服务器并从commons httpclient串行发送两个请求,commons httpclient也会关闭连接和第二个请求是在不同的连接中进行的。另一方面,如果我代理请求,则第二个请求使用相同的连接,但是当我尝试将第二个请求的响应写入客户端通道时,我得到一个“连接重置”异常。

我的管道和基本处理程序的代码:

    ChannelFactory factory =
            new NioServerSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());
    ServerBootstrap sb = new ServerBootstrap(factory);

    sb.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(
                    new HttpRequestDecoder(),
                    new HttpResponseEncoder(),
                    new RequestHandler());
        }
    });

private static class RequestHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
        HttpResponse clientResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        clientResponse.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/html; charset=UTF-8");
        clientResponse.setContent(ChannelBuffers.wrappedBuffer(new byte[] {1, 2, 3}));
        System.out.println("here: " + e.getChannel());
        e.getChannel().write(clientResponse);
    }
}

这是端口 2080 上的 tcpdump,显示客户端正在关闭连接(open-handshake、push、push、close-handshake、open-handshake、push、push、close-handshake):

[master] sudo tcpdump -i any '(port 2080)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
15:13:22.396482 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [S], seq 3122841582, win 32792, options [mss 16396,sackOK,TS val 880723828 ecr 0,nop,wscale 7], length 0
15:13:22.396499 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.45724: Flags [S.], seq 604436385, ack 3122841583, win 32768, options [mss 16396,sackOK,TS val 880723829 ecr 880723828,nop,wscale 7], length 0
15:13:22.396511 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [.], ack 1, win 257, options [nop,nop,TS val 880723829 ecr 880723829], length 0
15:13:22.406805 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [P.], seq 1:1600, ack 1, win 257, options [nop,nop,TS val 880723839 ecr 880723829], length 1599
15:13:22.406817 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.45724: Flags [.], ack 1600, win 256, options [nop,nop,TS val 880723839 ecr 880723839], length 0
15:13:22.446068 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.45724: Flags [P.], seq 1:63, ack 1600, win 256, options [nop,nop,TS val 880723878 ecr 880723839], length 62
15:13:22.446083 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [.], ack 63, win 257, options [nop,nop,TS val 880723878 ecr 880723878], length 0
15:13:22.449192 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [F.], seq 1600, ack 63, win 257, options [nop,nop,TS val 880723881 ecr 880723878], length 0
15:13:22.449360 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.45724: Flags [F.], seq 63, ack 1601, win 256, options [nop,nop,TS val 880723881 ecr 880723881], length 0
15:13:22.449371 IP localhost.localdomain.45724 > localhost.localdomain.autodesk-nlm: Flags [.], ack 64, win 257, options [nop,nop,TS val 880723881 ecr 880723881], length 0
15:13:22.449716 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [S], seq 929672323, win 32792, options [mss 16396,sackOK,TS val 880723882 ecr 0,nop,wscale 7], length 0
15:13:22.449729 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.35737: Flags [S.], seq 1626218986, ack 929672324, win 32768, options [mss 16396,sackOK,TS val 880723882 ecr 880723882,nop,wscale 7], length 0
15:13:22.449737 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [.], ack 1, win 257, options [nop,nop,TS val 880723882 ecr 880723882], length 0
15:13:22.449986 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [P.], seq 1:1600, ack 1, win 257, options [nop,nop,TS val 880723882 ecr 880723882], length 1599
15:13:22.449992 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.35737: Flags [.], ack 1600, win 256, options [nop,nop,TS val 880723882 ecr 880723882], length 0
15:13:22.453566 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.35737: Flags [P.], seq 1:63, ack 1600, win 256, options [nop,nop,TS val 880723886 ecr 880723882], length 62
15:13:22.453582 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [.], ack 63, win 257, options [nop,nop,TS val 880723886 ecr 880723886], length 0
15:13:22.475867 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [F.], seq 1600, ack 63, win 257, options [nop,nop,TS val 880723908 ecr 880723886], length 0
15:13:22.475998 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.35737: Flags [F.], seq 63, ack 1601, win 256, options [nop,nop,TS val 880723908 ecr 880723908], length 0
15:13:22.476012 IP localhost.localdomain.35737 > localhost.localdomain.autodesk-nlm: Flags [.], ack 64, win 257, options [nop,nop,TS val 880723908 ecr 880723908], length 0

如果我使用代理会发生以下情况,该代理实质上是从 中保存通道messageReceived(),并稍后查找该通道以编写响应。请注意,这里的通道没有关闭,而是由客户端重置,导致 IOException 'connection reset':

[master] sudo tcpdump -i any '(port 2080)'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
15:11:02.055316 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [S], seq 1055230627, win 32792, options [mss 16396,sackOK,TS val 880583487 ecr 0,nop,wscale 7], length 0
15:11:02.055333 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.58266: Flags [S.], seq 596566447, ack 1055230628, win 32768, options [mss 16396,sackOK,TS val 880583487 ecr 880583487,nop,wscale 7], length 0
15:11:02.055344 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [.], ack 1, win 257, options [nop,nop,TS val 880583487 ecr 880583487], length 0
15:11:02.066169 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [P.], seq 1:1600, ack 1, win 257, options [nop,nop,TS val 880583498 ecr 880583487], length 1599
15:11:02.066188 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.58266: Flags [.], ack 1600, win 256, options [nop,nop,TS val 880583498 ecr 880583498], length 0
15:11:02.071439 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.58266: Flags [P.], seq 1:1568, ack 1600, win 256, options [nop,nop,TS val 880583503 ecr 880583498], length 1567
15:11:02.071450 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [.], ack 1568, win 256, options [nop,nop,TS val 880583503 ecr 880583503], length 0
15:11:02.076384 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [P.], seq 1600:3199, ack 1568, win 256, options [nop,nop,TS val 880583508 ecr 880583503], length 1599
15:11:02.080625 IP localhost.localdomain.autodesk-nlm > localhost.localdomain.58266: Flags [P.], seq 1568:3135, ack 3199, win 256, options [nop,nop,TS val 880583513 ecr 880583508], length 1567
15:11:02.102018 IP localhost.localdomain.58266 > localhost.localdomain.autodesk-nlm: Flags [R.], seq 3199, ack 3135, win 256, options [nop,nop,TS val 880583534 ecr 880583513], length 0

我的处理程序中是否缺少一些东西来阻止客户端关闭连接?

编辑:阅读响应似乎会导致连接重置消失并且连接被正常断开。知道为什么这个 println 会在第二次请求后阻止连接重置吗?

httpClient.executeMethod(method);
System.out.println(method.getResponseBodyAsString());
4

2 回答 2

1

您的处理程序正在发送 HTTP v1.1 响应,其中 keep-alive 是默认连接类型,因此只要您的客户端期望 v1.1 而不是 v1.0,并且行为正确,那么您不必做任何事情更多以指示客户端保持连接打开。

如果您的客户端期待 HTTP v1.0,您可以添加一个“Connection: keep-alive”标头。

于 2013-04-08T00:09:05.017 回答
0

终于想通了。有几个问题。最重要的问题是我没有从发起对该代理的调用的公共 HttpClient 调用 method.releaseConnection()。出于某种原因,调用 getResponseBodyAsString() 或 getResponseBodyAsStream.close() 也消除了重置问题。

于 2013-04-08T19:58:27.570 回答