Question

I'm using Netty 4 for sending a protocol string to a device that should answer with another protocol string. I have done two classes, EthClient and EthClientHandler.

EthClient:

connection = new EthClientHandler(message);
b.group(group)
        .channel(NioSocketChannel.class)
        .remoteAddress(host, port)
        .option(ChannelOption.TCP_NODELAY, true)
        .option(ChannelOption.SO_KEEPALIVE, true)
        .handler(new ChannelInitializer<SocketChannel>() {
              @Override
              public void initChannel(SocketChannel ch) throws Exception {
                  ch.pipeline().addLast(
                      new DelimiterBasedFrameDecoder(2048, true, Unpooled.copiedBuffer("\u0004".getBytes())),
                      new StringEncoder(),
                      new StringDecoder(),
                      new ReadTimeoutHandler(READ_TIMEOUT, TimeUnit.SECONDS),
                      connection
                   );
              }
        });
f = b.connect();
f.channel().closeFuture();
...

EthClientHandler:

public class EthClientHandler extends SimpleChannelInboundHandler<String> {
 private String message;

 public EthClientHandler(message) {
       this.message = message;
 }

 @Override
 public void channelActive(ChannelHandlerContext ctx) {
     ctx.writeAndFlush(message);
 }

 @Override
 public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
      gestString(msg);
      ctx.writeAndFlush(message);
 }
}

When start connection it send protocol string but device doesn't answer me. Using Wireshark to understand if device answer something I found this conversation:

 445    2.835161000 192.168.1.135   192.168.1.252   TCP 54  49570 > exlm-agent [FIN, ACK] Seq=1 Ack=1 Win=65088 Len=0
 454    2.871899000 192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 49570 [FIN, ACK] Seq=1 Ack=2 Win=256 Len=0
 455    2.871947000 192.168.1.135   192.168.1.252   TCP 54  49570 > exlm-agent [ACK] Seq=2 Ack=2 Win=65088 Len=0
 617    3.835746000 192.168.1.135   192.168.1.252   TCP 66  49575 > exlm-agent [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=4 SACK_PERM=1
 622    3.866775000 192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 49575 [SYN, ACK] Seq=0 Ack=1 Win=256 Len=0 MSS=576
 623    3.866839000 192.168.1.135   192.168.1.252   TCP 54  49575 > exlm-agent [ACK] Seq=1 Ack=1 Win=65088 Len=0
 624    3.867209000 192.168.1.135   192.168.1.252   IPA 57  unknown 0x04 [Malformed Packet]
 641    3.937626000 192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 49575 [ACK] Seq=1 Ack=4 Win=256 Len=0

So after the last ACK I didn't received anything else and connection went in Read Timeout. If I put a breakpoint in my code on the ctx.writeAndFlush(message) at channel sturtup and after a second I resume the program device send me protocol string:

2036    13.113369000    192.168.1.135   192.168.1.252   TCP 66  51135 > exlm-agent [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=4 SACK_PERM=1
2037    13.144752000    192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 51135 [SYN, ACK] Seq=0 Ack=1 Win=256 Len=0 MSS=576
2038    13.144833000    192.168.1.135   192.168.1.252   TCP 54  51135 > exlm-agent [ACK] Seq=1 Ack=1 Win=65088 Len=0
2069    13.319494000    192.168.1.135   192.168.1.252   IPA 57  unknown 0x04 [Malformed Packet]
2073    13.366926000    192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 51135 [ACK] Seq=1 Ack=4 Win=256 Len=0
2092    13.458136000    192.168.1.252   192.168.1.135   IPA 72  unknown 0x30 [Malformed Packet]
2093    13.460564000    192.168.1.135   192.168.1.252   IPA 57  unknown 0x04 [Malformed Packet]
2102    13.514205000    192.168.1.252   192.168.1.135   TCP 60  exlm-agent > 51135 [ACK] Seq=19 Ack=7 Win=256 Len=0
2123    13.621507000    192.168.1.252   192.168.1.135   IPA 72  unknown 0x30 [Malformed Packet]

So I really don't understand why this kind of result. Someone know how can I resolve it? It could be a Netty problem or a device problem?

Edit: Added DelimiterBasedFramdeDecoder in the bootstrap handler but result doesn't change. At first startup it receive correctly protocol string from device but if I try to disconnect e reconnect the problem come out again.

Was it helpful?

Solution 2

Resolved adding a pause before ctx.writeAndFlush(message) in EthClientHandler class in channelActive.

@Override
public void channelActive(final ChannelHandlerContext ctx) {

    ctx.channel().eventLoop().schedule(new Runnable() {
        @Override
        public void run() {
            ctx.writeAndFlush(message);
        }
    }, 1, TimeUnit.SECONDS);
}

Thanks for your help

OTHER TIPS

StringDecoder requires a framing decoder in front of it. Place a LineBasedFrameDecoder to handle a text line properly.

StringEncoder does not append "\r\n" for you. If you did not, please do.

These two changes will probably make it work.

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