Reputation: 21
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.
Upvotes: 2
Views: 999
Reputation: 21
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
Upvotes: 0
Reputation: 12351
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.
Upvotes: 3