您当前的位置: 首页 > 

小志的博客

暂无认证

  • 2浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Netty——ByteBuffer(ByteBuffer消息粘包、半包示例)

小志的博客 发布时间:2022-07-26 21:21:28 ,浏览量:2

目录
    • 一、 ByteBuffer消息粘包、消息半包的概述
    • 二、示例需求
    • 三、示例代码

一、 ByteBuffer消息粘包、消息半包的概述
  • NIO是面向缓冲区进行通信的,不是面向流的。既然是缓冲区,那它一定存在一个固定大小。这样一来通常会遇到两个问题:
  • 消息粘包:当缓冲区足够大,由于网络不稳定种种原因,可能会有多条消息从通道读入缓冲区,此时如果无法分清数据包之间的界限,就会导致粘包问题;
  • 消息半包:若消息没有接收完,缓冲区就被填满了,会导致从缓冲区取出的消息不完整,即半包的现象。
二、示例需求

网络上有多条数据发送给服务端,数据之间使用 \n 进行分隔,但由于某种原因这些数据在接收时,被进行了重新组合,例如原始数据有3条:

  • Hello,world\n
  • I’m zhangsan\n
  • How are you?\n

变成了下面的两个 byteBuffer (黏包,半包)

  • Hello,world\nI’m zhangsan\nHo
  • w are you?\n

现在要求你编写程序,将错乱的数据恢复成原始的按 \n 分隔的数据

三、示例代码
  • 需求代码

    package com.example.nettytest.nio.day1;
    
    import java.nio.ByteBuffer;
    import static com.example.nettytest.nio.day1.ByteBufferUtil.debugAll;
    /**
     * @description:
     * @author: xz
     * @create: 2022-07-26 21:10
     */
    public class TestByteBufferExam {
        public static void main(String[] args) {
            //分配一个新的字节缓冲区,容量为50
            ByteBuffer sourceByteBuffer = ByteBuffer.allocate(50);
            //写入数据
            sourceByteBuffer.put("Hello,world\nI'm zhangsan\nHo".getBytes());
    
            split(sourceByteBuffer);
            //再次写入数据
            sourceByteBuffer.put("w are you?\n".getBytes());
    
            split(sourceByteBuffer);
        }
        /**
         * 将错乱的数据恢复成原始的按 \n 分隔的数据方法
         * */
        public static void split(ByteBuffer sourceByteBuffer){
            //flip 切换到读模式
            sourceByteBuffer.flip();
            for(int i = 0; i > 4];
        private static final String[] BYTE2HEX = new String[256];
        private static final String[] BYTEPADDING = new String[16];
    
        static {
            final char[] DIGITS = "0123456789abcdef".toCharArray();
            for (int i = 0; i  4 & 0x0F];
                HEXDUMP_TABLE[(i             
关注
打赏
1661269038
查看更多评论
0.1132s