netty拆包、粘包的问题:服务端接收tcp请求的时候,为什么需要数据拼装?或者是接收什么样的数据需要数据拼装?

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类型来解析的话,的确是会乱码。
但现实真的会有这种情况存在吗?有大佬给两个具体一点的例子么?

阅读 3.8k
2 个回答

其实这就是一个典型的粘包、拆包的问题。

导致的原因就是因为 TCP 是流式的,就像水流一样没法知道一段完整的报文到哪里是截止的。

报文越长就越可能出现这样的问题。

文中提到的其实是按照字节长度来防止拆包,常见的还有通过分隔符,比如知道读取到指定的分隔符才算做是获取到了完整的报文。

这些其实 Netty 都是有内置的处理器。

新手上路,请多包涵

发数据的时候for循环多发几次数据,就可以看出粘包效果了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题