Question

I'm trying to communicate with a server that uses DataInputStream.readUTF and DataOutputStream.writeUTF.

I did the usual bootstrapping code to setup my client, and set the following 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());
        }
    });

in MyClientHandler which extends SimpleChannelUpstreamHandler, I have the following:

    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
        }
    }

I managed to receive messages from server successfully, but server is not receiving my "hello over there" message. Not sure what I might have overlooked.

Also, notice the boolean sent, can I add such fields and work with them without threading concerns?

Was it helpful?

Solution

  • I managed to receive messages from server successfully, but server is not receiving my "hello over there" message. Not sure what I might have overlooked.

Because the message from the server was able to be received by using LengthFieldBasedFrameDecoder, the message has a length field.

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

Therefore, There is a possibility that the server will expect the received message has the length field. How if the length field is written as follows?

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

[sample]

@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
    }
}
  • Also, notice the boolean sent, can I add such fields and work with them without threading concerns?

Yes, you can add the fields to store some state. And you need not consider the synchronization of the thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top