Netty拆包粘包

超、凢脫俗 2022-11-15 11:41 370阅读 0赞

拆包

拆包是指netty传输数据时候,会把一条信息,拆成几部分。比如:”hello “拆成”he” 和 “llo”等,

粘包

粘包是指将多条信息连在一起 比如发送“hello”和”123”,而受到的是 “hello123”

解决方案:

  1. 消息定长,比如固定传100字符,不够的用空格补充
  2. 在尾部添加特殊字符
  3. 发送信息是发送信息长度

下面我们来看一下定长怎么用

客户端

  1. @Data
  2. public class MyMessageProtocol {
  3. //定义一次发送包体长度
  4. private int len;
  5. //一次发送包体内容
  6. private byte[] content;
  7. }
  8. public class NettyClientHandler extends SimpleChannelInboundHandler<MyMessageProtocol> {
  9. /**
  10. * 当客户端连接服务器完成就会触发该方法
  11. *
  12. * @param ctx
  13. * @throws Exception
  14. */
  15. @Override
  16. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  17. for(int i = 0; i< 10; i++) {
  18. String msg = "检测拆包";
  19. //创建协议包对象
  20. MyMessageProtocol messageProtocol = new MyMessageProtocol();
  21. messageProtocol.setLen(msg.getBytes(CharsetUtil.UTF_8).length);
  22. messageProtocol.setContent(msg.getBytes(CharsetUtil.UTF_8));
  23. ctx.writeAndFlush(messageProtocol);
  24. }
  25. }
  26. }
  27. public class PackMessageEncoder extends MessageToByteEncoder<MyMessageProtocol> {
  28. @Override
  29. protected void encode(ChannelHandlerContext ctx, MyMessageProtocol msg, ByteBuf out) throws Exception {
  30. System.out.println("MyMessageEncoder encode 方法被调用");
  31. out.writeInt(msg.getLen());
  32. out.writeInt(msg.getLen());
  33. out.writeBytes(msg.getContent());
  34. }
  35. }

服务端

  1. public class PackNettyServerHandler extends SimpleChannelInboundHandler<MyMessageProtocol> {
  2. @Override
  3. protected void channelRead0(ChannelHandlerContext ctx, MyMessageProtocol msg) throws Exception {
  4. System.out.println("====服务端接收到消息如下====");
  5. System.out.println("长度=" + msg.getLen());
  6. System.out.println("内容=" + new String(msg.getContent(), CharsetUtil.UTF_8));
  7. }
  8. @Override
  9. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  10. cause.printStackTrace();
  11. ctx.close();
  12. }
  13. }
  14. public class PackMessageDecoder extends ByteToMessageDecoder {
  15. int length = 0;
  16. @Override
  17. protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  18. //int类型长度4
  19. if(in.readableBytes() >= 4) {
  20. //获取到长度
  21. if (length == 0){
  22. length = in.readInt();
  23. }
  24. if (in.readableBytes() < length) {
  25. System.out.println("当前可读数据不够,继续等待。。");
  26. return;
  27. }
  28. byte[] content = new byte[length];
  29. if (in.readableBytes() >= length){
  30. in.readBytes(content);
  31. //封装成MyMessageProtocol对象,传递到下一个handler业务处理
  32. MyMessageProtocol messageProtocol = new MyMessageProtocol();
  33. messageProtocol.setLen(length);
  34. messageProtocol.setContent(content);
  35. //交给下个handler处理
  36. out.add(messageProtocol);
  37. }
  38. length = 0;
  39. }
  40. }
  41. }

发表评论

表情:
评论列表 (有 0 条评论,370人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Netty/

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接。由于微服务往对方发送信息

    相关 Netty

    拆包 拆包是指netty传输数据时候,会把一条信息,拆成几部分。比如:"hello "拆成"he" 和 "llo"等, 粘包 粘包是指将多条信息连在一起 比如发送

    相关 Netty之TCP问题

           粘包拆包问题是处于网络比较底层的问题,在数据链路层、网络层以及传输层都有可能发生。我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生这个问

    相关 5.Netty之TCP

    TCP网络传输之拆包粘包。 产生原因 熟悉tcp的都知道内部有个滑动窗口协议,分组以及限流。 数据包大于缓冲区 MSS大小的TCP分段 以太网pay