Нетти-клиент не может прочитать ответ от не-нетти-сервера - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть клиент Tcp, который подключается к старому мэйнфрейму (52 года), который отправляет и получает запрос и ответ от него.

Вот часть основного соединения моего клиента,

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

Я пытаюсь переписать следующую часть, используя Netty.Используя следующий учебник в качестве справочного материала.

Проблема, с которой я сталкиваюсь, заключается в том, что я смог подключиться к серверу, но не смог ни прочитать, ни написать с него.Я использую ChannelInboundHandlerAdapter для выполнения операций чтения и записи.

Вот мой 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");
        }
    }
}
}

Обработчик

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" );
    }
}

Я изначально думал, что netty будет работать только с серверами netty. Но этот ответ прояснит мои сомнения по этому поводу

Работает ли Netty-клиент только с сетевым сервером?

Может ли кто-нибудь подсказать мне, что я делаю неправильно ???

1 Ответ

0 голосов
/ 20 декабря 2018

Я думаю, что проблема с вашим ClientHandler.Вы должны writeAndFlush() в channelActive метод вызываться, когда установлено соединение между tcp-сервером и клиентом.Пожалуйста, используйте приведенный ниже обновленный код и посмотрите, решит ли он проблему.

    @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));
        }

    }
...