2011-01-24 64 views
1

我想與使用DataInputStream.readUTF和DataOutputStream.writeUTF的服務器通信。如何使用netty在對方使用readUTF/writeUTF時讀寫?

我做了通常的啓動代碼設置我的客戶,並在MyClientHandler延伸SimpleChannelUpstreamHandler設置以下pipelinefactory

bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 

     @Override 
     public ChannelPipeline getPipeline() throws Exception { 
      return Channels.pipeline(
        new LengthFieldBasedFrameDecoder(65536, 0, 2), 
        new StringDecoder(CharsetUtil.UTF_8), 
        new StringEncoder(CharsetUtil.UTF_8), 
        new MyClientHandler()); 
     } 
    }); 

,我有以下幾點:

boolean sent = false; //is this thread safe? 

    @Override 
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { 
     logger.log(Level.INFO, e.getMessage().toString()); 
     e.getChannel().write("Hello over there!"); 

     if(!sent){ 
      //do something and set sent 
     } 
    } 

我設法接收消息從服務器成功,但服務器沒有收到我的「你好那邊」的消息。不知道我可能忽略了什麼。

此外,請注意布爾發送,我可以添加這樣的領域,並與他們一起工作,而無需線程擔憂?

回答

3
  • 我設法從服務器成功接收消息,但服務器沒有收到我的「你好那邊」消息。不知道我可能忽略了什麼。

因爲可以通過使用LengthFieldBasedFrameDecoder接收服務器的消息,所以消息有一個長度字段。

+--------+----------+ 
| Length | Message | 
+--------+----------+ 

因此,服務器有可能期望接收到的消息具有長度字段。 如果長度字段的寫法如下?

+--------+---------------------+ 
| 0x0011 | "Hello over there!" | 
+--------+---------------------+ 

[示例]

@Override 
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { 
    logger.log(Level.INFO, e.getMessage().toString()); 
    byte[] message = "Hello over there!".getBytes("UTF-8"); 

    ChannelBuffer buf = ChannelBuffers.buffer(message.length + 2); 
    buf.clear(); 
    short len = (short)message.length; 
    buf.writeShort(len); 
    buf.writeBytes(message); 
    e.getChannel().write(buf); 

    if(!sent){ 
     //do something and set sent 
    } 
} 
  • 另外,還要注意所發送的布爾,我可以添加等領域,並沒有關注螺紋與他們合作?

是的,你可以添加字段來存儲一些狀態。 而你不需要考慮線程的同步。

+0

我認爲更簡潔的方法是將org.jboss.netty.handler.codec.frame.LengthFieldPrepender添加到服務器管道。這會自動將長度字段預先添加到傳出數據包。 – Abe 2011-05-04 08:01:59