阻止客户端关闭与 netty 服务器的连接(我需要设置啥)?
Posted
技术标签:
【中文标题】阻止客户端关闭与 netty 服务器的连接(我需要设置啥)?【英文标题】:Keep client from closing connection to a netty server (is there something I need to set)?阻止客户端关闭与 netty 服务器的连接(我需要设置什么)? 【发布时间】:2013-03-28 12:02:39 【问题描述】:我正在调试我正在编写的 netty 代理的问题,我注意到即使我跳过“代理”方面并实现一个简单的 http 服务器并从公共 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,显示客户端正在关闭连接(打开握手、推送、推送、关闭握手、打开握手、推送、推送、关闭握手):
[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());
【问题讨论】:
【参考方案1】:您的处理程序正在发送一个 HTTP v1.1 响应,其中 keep-alive 是默认连接类型,因此只要您的客户端期望 v1.1 而不是 v1.0,并且行为正确,那么您就不应该有做更多的事情来指示客户端保持连接打开。
如果您的客户端期待 HTTP v1.0,您可以添加“Connection: keep-alive”标头。
【讨论】:
如果保持活动是问题,客户端不会发送 FIN 而不是 RST 吗?【参考方案2】:终于想通了。有几个问题。最重要的问题是我没有从发起对该代理的调用的公共 HttpClient 调用 method.releaseConnection()。由于某种原因,调用 getResponseBodyAsString() 或 getResponseBodyAsStream.close() 也消除了重置问题。
【讨论】:
以上是关于阻止客户端关闭与 netty 服务器的连接(我需要设置啥)?的主要内容,如果未能解决你的问题,请参考以下文章