2014-09-30 61 views
0

我開始熟悉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 

我將不勝感激,如果有人有這個奇怪的解釋...

回答

0

這個問題原來是cau sed由防病毒軟件。 顯然,我使用的軟件是使用hacky解析器進行HTTP監控,並且它吃掉了我的「請求」,這實際上是無效的......最後缺少額外的\ r \ n。

關閉防病毒解決了問題。並且還將請求糾正爲:

GET /index.html HTTP/1。0 \ r \ n \ r \ n

保持防病毒開心。

但爲什麼它決定吃

GET /index.html HTTP/1.0 \ r \ n

,而不是

GET /index.html HTTPA/1.0 \ r \ n

超出了我...