Netty client fail to read response from non-netty server

edwin :

I have a Tcp client that connect to a old mainframe (52 years) that send and receive request and response from it.

Here is core connection part of the my client ,

public class SimpleConnector {

    private String carrier;
    private SocketChannel socketChannel;
    public static final byte END_OF_MESSAGE_BYTE = (byte) 0x2b;

    public SimpleConnector(String carrier, InetSocketAddress inetSocketAddress) throws IOException {
        this.carrier = this.carrier;
        socketChannel = SocketChannel.open();
        socketChannel.socket().connect(inetSocketAddress, 30000);
    }

    public void shutDown() throws IOException {
        this.socketChannel.close();
    }
    //Send Request
    public String sendRequest(String request) throws Exception {
            final CharsetEncoder charsetEncoder = Charset.forName("ISO-8859-1").newEncoder();
            int requestLength = 12 + request.length() + 1;
            ByteBuffer buffer = ByteBuffer.allocate(requestLength);
            buffer.order(ByteOrder.BIG_ENDIAN);
            buffer.putInt(requestLength);
            buffer.put(charsetEncoder.encode(CharBuffer.wrap(carrier)));
            buffer.put(charsetEncoder.encode(CharBuffer.wrap(request)));
            buffer.put(END_OF_MESSAGE_BYTE);
            buffer.flip();
            socketChannel.write(buffer);
            return readResponse();

    }
    //Read Response
    protected String readResponse() throws Exception {
            CharsetDecoder charsetDecoder = Charset.forName("ISO-8859-1").newDecoder();
            int responseHeaderLength = 12;
            ByteBuffer responseHeaderBuf = ByteBuffer.allocate(responseHeaderLength);
            responseHeaderBuf.order(ByteOrder.BIG_ENDIAN);
            int bytesRead = 0;
            do {
                bytesRead = socketChannel.read(responseHeaderBuf);
            } while (bytesRead!=-1 && responseHeaderBuf.position()<responseHeaderLength);

            if (bytesRead==-1) {
                throw new IOException(carrier + " : Remote connection closed unexpectedly");
            }
            responseHeaderBuf.flip();
            int lengthField = responseHeaderBuf.getInt();
            int responseLength = lengthField - responseHeaderLength;
            responseHeaderBuf.clear();
            ByteBuffer responseBuf = ByteBuffer.allocate(responseLength);
            bytesRead = socketChannel.read(responseBuf);
            if (bytesRead>responseBuf.limit() || bytesRead ==-1) {
                throw new IOException(carrier + " : Remote connection closed unexpectedly");
            }
            responseBuf.flip();
            if (responseBuf.get(responseBuf.limit()-1)==END_OF_MESSAGE_BYTE) {
                responseBuf.limit(responseBuf.limit()-1);
            }
            responseBuf.clear();
            String response = charsetDecoder.decode(responseBuf).toString();
            return response;

    }

    public static void main(String[] args) throws Exception{
        SimpleConnector simpleConnector = new SimpleConnector("carrier",new InetSocketAddress("localhost",9999));
        String response=simpleConnector.sendRequest("Request");
        System.out.println(response);
    }
}

I'm trying to rewrite the following piece using Netty. By using following tutorial as reference.

The problem I'm facing is I was able to connect to server but couldn't read or write from it . I'm using a ChannelInboundHandlerAdapter to do the read and write operations.

Here is my Netty Client

public class NettyClient {
    int port;
    Channel channel;
    EventLoopGroup workGroup = new NioEventLoopGroup();

    public NettyClient(int port){
        this.port = port;
    }

    public ChannelFuture connectLoop() throws Exception {
        try{
            Bootstrap b = new Bootstrap();
            b.group(workGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addLast(new NettyClientHandler());
                }
            }); 
            ChannelFuture channelFuture = b.connect("remote-ip", this.port).sync();
            this.channel = channelFuture.channel();

            return channelFuture;
        }finally{
        }
    }
    public void shutdown(){
        workGroup.shutdownGracefully();
    }

    public static void main(String[] args) throws Exception{

        try {
            NettyClient nettyClient = new NettyClient(12000);
            ChannelFuture channelFuture = nettyClient.connectLoop();
            System.out.println("Sleep 2sec");
            Thread.sleep(2000);
            String command ="username";
            final Charset charset = Charset.forName("ISO-8859-1");
            int length = 13 + command.length();
            if (channelFuture.isSuccess()) {
                ByteBuf byteBuf = Unpooled.buffer(1024);
                byteBuf.writeInt(length);
                byteBuf.writeCharSequence("Some Info",charset);
                byteBuf.writeCharSequence(command,charset);
               channelFuture.channel().writeAndFlush(byteBuf).addListener(new ListenerImpl());

            }
        }
        catch(Exception e){
            System.out.println(e.getMessage());
            System.out.println("Try Starting Server First !!");
        }
        finally {
        }
    }
private static final class ListenerImpl implements ChannelFutureListener{

    public void operationComplete(ChannelFuture channelFuture) throws Exception {
        if (channelFuture.isSuccess()){
            System.out.println("Success"); //I can see success in Listener after write, but couldn't read response

        }else {
            System.out.println("Failed");
        }
    }
}
}

Handler

public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("NettyClientHandler : channelRead" );
        ByteBuf byteBuf = (ByteBuf) msg;
        String message = byteBuf.toString(Charset.defaultCharset());
        System.out.println("Received Message : " + message);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        System.out.println("NettyClientHandler : channelActive" );
    }
}

I Initially thought netty will work only with netty servers.But this answer clear my doubt about that

Does a Netty client work with a netty server only?

Can some one guide me, what I'm doing wrong ???

Rajkumar Natarajan :

I think the problem is with your ClientHandler. you should writeAndFlush() in channelActive method invoked when a connection has been established between the tcp server and client. Please use the below updated code and see whether it fixes the problem.

    @Sharable
    public class NettyClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

        @Override
        public void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
            String message = byteBuf.toString(Charset.defaultCharset());
            System.out.println("Received Message : " + message);
        }

        @Override
        public void channelActive(ChannelHandlerContext channelHandlerContext){
            channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("Netty Rocks!", CharsetUtil.UTF_8));
        }

    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=81052&siteId=1