编辑代码


/**
 数据结构,消息头为5个字节,剩余的是传输内容
 ---------------------------
 数据类型    |  长度      | 内容
 ---------------------------
 1字节       | 4字节     |
 ----------------------------
 */

let step = 1;
let msgType = 0;
let msgLen = 0;
let readedLen = 0;
let msgData;

function onRecived() {
    console.log("\n\ntype:%d, len:%d ,data:[", msgType, msgLen);
    for (let i = 0; i < msgLen; i++) {
        console.log("%d,", msgData[i]);
    }
    console.log("]\n\n");
}

/**
 * 处理包
 */
function packetIn(buff) {
    // if (size == 0) {
    //     return;
    // }
    buff = Buffer.from(buff);
    let buffPos = 0;
    let size = buff.length;
    console.log("packet:", JSON.stringify(buff));
    if (step == 1) {

        //read msg type
        msgType = buff.readInt8();

        size -= 1;
        //
        step = 2;
        msgLen = 0;
        readedLen = 0;
        buffPos++;
    }
    if (step == 2) {
        //read msg len
        let len;
        if (size >= 4 - readedLen) {
            len = 4 - readedLen;
        } else {
            len = size;
        }
        if (len != 4) {
            //需要通过移位
            if (len > 0) {
                for (let i = 0; i < len; i++) {
                    msgLen = msgLen << 8;
                    msgLen += buff.readInt8(buffPos++);
                }
                readedLen += len;
            }
        } else {
            msgLen = buff.readInt32BE(buffPos);
            buffPos += len;
            readedLen += len;
        }

        if (readedLen >= 4) {
            size -= len;
            step = 3;
            readedLen = 0;
        }
    }
    if (step == 3) {
        //read msg body
        let len = 0;
        if (msgLen > 0) {
            if (readedLen == 0) {
                msgData = [];
            }
            len = size > msgLen - readedLen ? msgLen - readedLen : size;
            for (let i = 0; i < len; i++) {
                msgData.push(buff[i]);
            }
            readedLen += len;
        }
        if (readedLen < msgLen) {
            //消息尚未完成
        } else {
            //消息读取完成
            onRecived();
            step = 1;
            if (msgLen > 0) {
                // free(msgData);
            }
        }
        if (size - len > 0) {
            size -= len;
            //粘包,继续读取剩余内容
            packetIn(buff.slice(buffPos, buff.length));
        }
    }
}

//测试数据,模拟拆包、粘包的数据结果

//完整包
let d0 = [15, 0, 0, 0, 1, 1];
packetIn(d0);

//拆包
let d1 = [1];
let d2 = [0, 0];
let d3 = [0, 3, 0];
let d4 = [0, 0];
packetIn(d1);
packetIn(d2);
packetIn(d3);
packetIn(d4);

// //粘包
let d5 = [2, 0, 0, 0, 0, 3, 0, 0, 0, 1, 5];
packetIn(d5);

// //粘包+拆包
let d6 = [4, 0, 0, 0, 0, 5, 0, 0, 0, 3, 1];
let d7 = [2, 3];
packetIn(d6);
packetIn(d7);

// //拆包 + 粘包 +拆包
let d8 = [6, 0];
let d9 = [0, 0, 3];
let d10 = [0, 0];
let d11 = [0, 7, 0, 0];
let d12 = [0, 3, 1];
let d13 = [2, 3];
packetIn(d8);
packetIn(d9);
packetIn(d10);
packetIn(d11);
packetIn(d12);
packetIn(d13);