TCP 数据包结构

TCP Packet Structure

有人可以帮我在 nodejs 中用这个数据包结构创建一个 tcp 数据包吗? enter image description here

   const net = require('net');
var createPacket = require("./MSPPacketHandler/createPacket");

var host = '192.168.4.1';
var port = 23;


let client = new net.Socket();
client.connect(port, host, () => {
    var str = "";
    console.log("Connected");
    client.write(createPacket("Roll",0x6c,">")); //This will send the byte buffer over TCP

    client.on('data',function(chunk){
        str += chunk;
    })

    client.on('end',function(){
        console.log(str);
    });
})
// Packet format
// Header bytes:     0x24, 0x4d
// Direction byte:   0x3c or 0x3e
// Msg Length:       0x00 to 0xff
// Command:          0x01 to 0xff
// Payload Bytes:    .....
// CRC               xx

function createPacket(payload_data,command,direction){
    const packetMainLength = 6; // fixed overhead of packet without payload
    const payload = payload_data; // string
    const packetLength = packetMainLength + payload.length;

    const buffer = Buffer.alloc(packetLength, 0);
    // write common MSP message header
    buffer[0] = 0x24;
    buffer[1] = 0x4d;

    // write direction
    buffer[2] = (direction == "<" ? 0x3c : 0x3e); // to the flight controller

    // write payload length
    buffer[3] = packetLength;

    // write command
    //buffer[4] = 0x6c; // pick the appropriate command to the controller
    buffer[4] = command;

    // put our payload string into the buffer
    buffer.write(payload, 5, payload.length, 'utf8');
    const afterIndex = 5 + payload.length;

    // calculate CRC of direction, length and payload and put it into the packet 
    // after the payload

    const crcStartIndex = 3;
    let crc = buffer[crcStartIndex];
    for (let index = 1; index < payload.length + 2; index++) {
        crc = crc ^ buffer[index + crcStartIndex];
    }

    buffer[afterIndex] = crc;

    console.log(buffer);

    return buffer;
    
}

module.exports = createPacket;

这是创建数据包的功能。它需要三个参数和 returns 缓冲区。我按原样发送了缓冲区,是否需要将其转换为字符串?添加一些随机文本,因为 Whosebug 要求添加更多描述。

创建一个 Buffer object 然后你可以使用 .writeInt8() 方法将单字节值放入缓冲区的正确位置(看起来你的格式都是单字节值)或 fir single字节值,您也可以使用数组语法直接索引到缓冲区。

您将必须手动了解哪些值进入缓冲区的哪些字节,包括有效载荷长度、有效载荷和有效载荷的 CRC(按照您的图片中的描述计算)。

例如,如果您的负载是字符串“Hello”中的字符,您可以像这样构造该数据包:

// Packet format
// Header bytes:     0x24, 0x4d
// Direction byte:   0x3c or 0x3e
// Msg Length:       0x00 to 0xff
// Command:          0x01 to 0xff
// Payload Bytes:    .....
// CRC               xx

const packetMainLength = 6; // fixed overhead of packet without payload
const payload = "Hello"
const packetLength = packetMainLength + payload.length;

const buffer = Buffer.alloc(packetLength, 0);
// write common MSP message header
buffer[0] = 0x24;
buffer[1] = 0x4d;

// write direction
buffer[2] = 0x3c; // to the flight controller

// write payload length
buffer[3] = packetLength;

// write command
buffer[4] = 0x1; // pick the appropriate command to the controller

// put our payload string into the buffer
buffer.write(payload, 5, payload.length, 'utf8');
const afterIndex = 5 + payload.length;

// calculate CRC of direction, length and payload and put it into the packet 
// after the payload

const crcStartIndex = 3;
let crc = buffer[crcStartIndex];
for (let index = 1; index < payload.length + 2; index++) {
    crc = crc ^ buffer[index + crcStartIndex];
}

buffer[afterIndex] = crc;

console.log(buffer);

由于其中大部分对于所有数据包都是通用的,您可以创建一个通用函数,将有效载荷、命令和方向作为函数参数,然后它会为您创建包含该数据的数据包。