我开始熟悉Netty,因为我打算在未来的项目中使用它。Netty不发送某些字符序列
但我偶然发现了一些奇怪的行为。
由于我将为项目使用文本协议,因此我开始使用带有StringDecoder,StringEncoder和DelimiterBasedFrameDecoder的标准“文本”管道。但现在我已经减少了这以下内容:
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TestClientHandler());
}
});
ChannelFuture f = b.connect("some.working.web.server", 80).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
而且我TestClient的是:
public static class TestClientHandler extends
SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
ctx.writeAndFlush(Unpooled.copiedBuffer(
"GET /index.html HTTP/1.0\r\n", CharsetUtil.US_ASCII));
System.out.println("after write");
}
@Override
public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
System.out.println("got" + msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
我看着交通使用Wireshark而当这是唯一的执行进行TCP握手,没有什么是发送。过了一段时间程序退出(当HTTP服务器关闭连接时)。
最奇怪的是,如果我改变行:
ctx.writeAndFlush(Unpooled.copiedBuffer(
"GET /index.html HTTP/1.0\r\n", CharsetUtil.US_ASCII));
到
ctx.writeAndFlush(Unpooled.copiedBuffer(
"GET /index.html HTTPA1.0\r\n", CharsetUtil.US_ASCII));
然后“请求”被发送到这当然拒绝,并返回一个错误提示服务器。
我打了“请求字符串”多一点,似乎Netty中由于某种原因不喜欢以下内容:
ctx.writeAndFlush(Unpooled.copiedBuffer(
" HTTP/1.0\n", CharsetUtil.US_ASCII));
此字符串不会发送。但删除前导空格或更改随机字符会将字符串发送到服务器。
为了让事情变得更加奇怪,如果我用SMTP服务器测试这个,“请求”会在没有问题的情况下发送到服务器。唯一的区别是SMTP服务器在将字符串发送到服务器之前发送HELO消息...
此行为与Java 1.7.0_21和1.8上的Netty 4.0.23和4.1.0.Beta3也相同.0_20。 并且还保持不变,如果我改变OioEventLoopGroup和OioSocketChannel
而且改变channelActive方法的位:
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
ByteBuf bb = Unpooled.buffer();
bb.writeBytes("GET index.htm HTTP/1.0\r\n".getBytes());
System.out.println(ByteBufUtil.hexDump(bb));
ctx.writeAndFlush(bb);
System.out.println("after write");
}
可见我的“要求”得到了变成字节的正确顺序:
47455420696e6465782e68746d20485454502f312e300d0a
G E T i n d e x . h t m H T T P/1 . 0 \r\n
我将不胜感激,如果有人有这个奇怪的解释...