【问题标题】:Netty binary data not flush out until 0x0aNetty 二进制数据直到 0x0a 才被刷新
【发布时间】:2017-05-01 18:34:49
【问题描述】:

我的 netty 服务器应用程序需要用二进制数据回复客户端,但似乎只有在到达 0x0a 时才会刷新。

private Logger _log = LoggerFactory.getLogger(getClass());
private EventLoopGroup _masterGroup = new NioEventLoopGroup();
private EventLoopGroup _workerGroup = new NioEventLoopGroup();
private ByteArrayDecoder _decoder = new ByteArrayDecoder();
private ByteArrayEncoder _encoder = new ByteArrayEncoder();
private Channel _channel;

@PostConstruct
public void start() throws InterruptedException {
    _log.info("component ready");

    ServerBootstrap bootstrap = new ServerBootstrap()
            .channel(NioServerSocketChannel.class)
            .group(_masterGroup, _workerGroup)
            .option(ChannelOption.SO_BACKLOG, 100)
            .option(ChannelOption.TCP_NODELAY, true)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel channel) throws Exception {
                    ChannelPipeline pipe = channel.pipeline();

                    pipe.addLast(_decoder);
                    pipe.addLast(_encoder);
                    pipe.addLast(new ChannelDuplexHandler() {
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) {
                            byte[] data = (byte[])msg;
                            StringBuffer buf = new StringBuffer();

                            for(byte b : data) {
                                buf.append(String.format("%02x", b)).append(" ");
                            }

                            _log.info(buf.toString());

                            ctx.writeAndFlush(new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x0a, 0x36, 0x37 });
                        }
                    });
                }

            });

    _channel = bootstrap.bind(8090).sync().channel().closeFuture().sync().channel();
    _log.info("server readey, listening port: 8090");
}

预期的结果应该是一个 8 字节的数组,但我只得到了 5 个字节。那么,发送缓冲区的正确方法是什么?

编辑:添加我的测试程序

private String send(byte[] msg) {
    InputStream in = null;
    OutputStream out = null;
    Socket socket = null;
    String result = null;

    try {
        _log.debug("connecting...");
        socket = new Socket();
        socket.connect(new InetSocketAddress(_ip, _port), 500);
        socket.setKeepAlive(false);

        _log.debug("sending message...");
        out = socket.getOutputStream();
        out.write(msg);
        out.flush();

        _log.debug("reading response...");
        in = socket.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        while(null != (result = reader.readLine())) {
            printBuffer("server response", result.getBytes());
        }
    } catch(Exception e) {
        _log.error(e.getMessage());
    } finally {
        try {
            if(null != in) in.close();
            if(null != out) out.close();
            if(null != socket) socket.close();
        } catch(IOException e) {
            _log.error(e.getMessage());
        }
    }

    return result;
}

【问题讨论】:

  • 可以给我们看一下_encoder的代码吗?
  • _encoder 在顶部被声明为 ByteArrayEncoder,它来自 netty。

标签: java spring-boot websocket netty


【解决方案1】:

服务器工作正常,就像一个测试程序。但是您使用 readLine() 方法读取响应,该方法逐行读取字节。第一行是 [0x31, 0x32, 0x33, 0x34, 0x35],然后 [0x0a] 是“新行”字符,它不包含在 readLine() 的结果中。然后换行 [0x36, 0x37],但是这行没有“换行”或“回车”之类的结尾,所以也不显示。

你应该重写你的测试程序,让它读取和显示字节流而不是行。

【讨论】:

  • 你说得对,是我测试客户端程序的问题。我只是使用 ByteArrayOutputStream 重写了我的测试客户端解决了这个问题。
猜你喜欢
  • 2014-03-22
  • 1970-01-01
  • 2019-07-12
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多