How to read/write with netty when other side is using readUTF/writeUTF?
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?
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.