Netty 二进制数据直到 0x0a 才被刷新
Netty binary data not flush out until 0x0a
我的 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;
}
服务器运行正常,就像测试程序一样。但是您使用 readLine() 方法读取响应,该方法逐行读取字节。第一行是 [0x31, 0x32, 0x33, 0x34, 0x35],然后 [0x0a] 是 "new line" 字符,它不包含在 readLine() 的结果中。然后换行[0x36, 0x37],但是这一行没有结尾比如"line feed"或者"carriage return",所以也没有显示
您应该重写您的测试程序,以便它读取和显示字节流而不是行。
我的 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;
}
服务器运行正常,就像测试程序一样。但是您使用 readLine() 方法读取响应,该方法逐行读取字节。第一行是 [0x31, 0x32, 0x33, 0x34, 0x35],然后 [0x0a] 是 "new line" 字符,它不包含在 readLine() 的结果中。然后换行[0x36, 0x37],但是这一行没有结尾比如"line feed"或者"carriage return",所以也没有显示
您应该重写您的测试程序,以便它读取和显示字节流而不是行。