netty官网的user-guide里的demo,有一个小节的内容弄的不是特别明白。
原文:netty4.x用户指南
中文:netty4.x用户指南
文章里说的,客户端发过来的数据包,服务端是以流的形式接收的,因此需要有一个处理逻辑,来将接收到的流解析成客户端发送来的真正的一个个的数据包。
但是我在自己的demo里,感觉不到这样做的必要额?因为客户端每发过来一段字符串,服务端都能通过
String recMsg = byteBuf.toString(CharsetUtil.UTF_8);
完整地解析出来,并没觉得有必要进行文中所说的操作。
@Slf4j
public class EchoHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf buf = (ByteBuf) msg;
String msgStr = buf.toString(CharsetUtil.UTF_8);
log.info("receive message: {}", msgStr);
ChannelFuture f = ctx.write(buf);
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assert f == future;
ctx.close();
}
});
}
}
是我哪里理解的有偏差吗?
比如说,客户端写过来的数据并不只有字符串,里面还夹杂着其他类型的数据比如一个long类型?
ByteBuf time = ctx.alloc().buffer(4); // ChannelHandlerContext ctx
String dateNow = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
long curTime = System.currentTimeMillis();
time.writeBytes(dateNow.getBytes());
time.writeLong(curTime);
ctx.writeAndFlush(time);
如果客户端像这一行写数据,服务器单一按照string类型来解析的话,的确是会乱码。
但现实真的会有这种情况存在吗?有大佬给两个具体一点的例子么?
其实这就是一个典型的粘包、拆包的问题。
导致的原因就是因为
TCP
是流式的,就像水流一样没法知道一段完整的报文到哪里是截止的。报文越长就越可能出现这样的问题。
文中提到的其实是按照字节长度来防止拆包,常见的还有通过分隔符,比如知道读取到指定的分隔符才算做是获取到了完整的报文。
这些其实 Netty 都是有内置的处理器。