MST
星途 面试题库

面试题:Node.js TCP 数据包分片后如何确保重组顺序正确

在 Node.js 实现 TCP 数据包分片发送后,接收端重组时如何保证数据包按照发送顺序正确重组?阐述具体的实现机制,包括可能用到的标识符、算法等,并给出代码框架。
30.9万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

保证数据包按序重组的实现机制

  1. 标识符
    • 序列号(Sequence Number):在发送端为每个分片数据包分配一个唯一的序列号,通常从 0 开始,按顺序递增。接收端可以根据这个序列号来确定数据包的顺序。
  2. 算法
    • 缓存与排序算法:接收端接收到分片数据包后,先将其放入一个缓存队列中。根据序列号对缓存中的数据包进行排序,然后按照顺序依次取出重组。例如,可以使用 JavaScript 的数组作为缓存队列,利用数组的 sort 方法根据序列号进行排序。

代码框架

const net = require('net');

// 接收端
const server = net.createServer((socket) => {
    const packetBuffer = [];
    socket.on('data', (data) => {
        // 假设数据格式为:序列号(4 字节)+ 数据内容
        const sequenceNumber = data.readUInt32BE(0);
        const packetData = data.slice(4);
        packetBuffer.push({ sequenceNumber, packetData });
        packetBuffer.sort((a, b) => a.sequenceNumber - b.sequenceNumber);

        // 尝试重组数据包
        let completePacket = '';
        while (packetBuffer.length > 0 && packetBuffer[0].sequenceNumber === completePacket.length / 4) {
            completePacket += packetBuffer.shift().packetData.toString('utf8');
        }
        if (completePacket) {
            console.log('重组后的完整数据包:', completePacket);
        }
    });

    socket.on('end', () => {
        console.log('连接已关闭');
    });
});

server.listen(8080, () => {
    console.log('服务器已启动,监听端口 8080');
});


// 发送端
const client = new net.Socket();
client.connect(8080, '127.0.0.1', () => {
    const message = 'Hello, TCP Packet Fragmentation!';
    const maxFragmentSize = 10;
    for (let i = 0; i < message.length; i += maxFragmentSize) {
        const fragment = message.slice(i, i + maxFragmentSize);
        const buffer = Buffer.alloc(4 + fragment.length);
        buffer.writeUInt32BE(i / maxFragmentSize, 0);
        buffer.write(fragment, 4);
        client.write(buffer);
    }
    client.end();
});

在上述代码中:

  • 发送端为每个分片数据包添加了序列号,然后发送给接收端。
  • 接收端在接收到数据后,根据序列号进行排序并尝试重组数据包。当接收到的数据包序列号连续时,将其内容拼接成完整的数据包。