You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Node.js Socket接收R51-GPRS设备UTF-8 JSON数据时出现乱码的问题排查求助

解决R51-GPRS设备TCP JSON数据乱码与解析问题

核心问题分析

从你的描述和代码来看,乱码的主要原因有两个:

  • 错误将普通TCP连接当作WebSocket处理:你的代码默认所有新连接都是WebSocket请求,会尝试提取Sec-WebSocket-Key并返回握手响应,但R51-GPRS设备是直接发送UTF-8编码的JSON数据,根本不会发起WebSocket握手,这导致设备的初始JSON数据被错误解析成WebSocket握手帧,后续数据处理完全混乱。
  • TCP流的粘包/拆包未处理:TCP是面向流的协议,data事件触发时可能只收到JSON的一部分,直接转字符串或解析会导致格式错误,甚至乱码。

修复后的代码实现

下面是修正后的Node.js TCP服务代码,专门针对R51-GPRS设备的JSON数据接收场景:

var net = require('net');
var sockets = [];

net.createServer(function (socket) {
    console.log('设备已连接');
    let buffer = Buffer.from(''); // 用Buffer存储未完成的数据流

    socket.on('data', function(data) {
        // 拼接收到的二进制数据
        buffer = Buffer.concat([buffer, data]);
        
        try {
            // 尝试将Buffer转UTF-8字符串并解析JSON
            // 注意:如果设备有特定分隔符(比如换行),可以按分隔符拆分数据
            const jsonStr = buffer.toString('utf8');
            const jsonData = JSON.parse(jsonStr);
            
            console.log('解析成功的JSON数据:', jsonData);
            // 解析成功后清空buffer,准备接收下一条数据
            buffer = Buffer.from('');
        } catch (err) {
            // 解析失败,说明数据不完整(粘包/拆包),继续等待后续数据
            console.log('数据不完整,等待后续片段:', err.message);
        }
    });

    socket.on('end', function() {
        console.log('设备连接断开(end)');
        const index = sockets.indexOf(socket);
        if (index !== -1) sockets.splice(index, 1);
    });

    socket.on('close', function() {
        console.log('设备连接关闭(close)');
        const index = sockets.indexOf(socket);
        if (index !== -1) sockets.splice(index, 1);
    });

    socket.on('error', function(e) {
        console.log('连接错误:', e);
    });

    sockets.push(socket);
}).listen(7788, function() {
    console.log('TCP服务监听端口7788');
});

关键修复点说明

  • 移除WebSocket握手逻辑:完全去掉了针对WebSocket的Sec-WebSocket-Key处理和握手响应,因为R51-GPRS设备用的是普通TCP协议。
  • 用Buffer处理二进制数据流:不再直接将data转字符串,而是先拼接Buffer,确保能处理不完整的JSON片段(粘包/拆包场景)。
  • UTF-8显式编码:调用buffer.toString('utf8')显式指定编码,避免Node.js默认编码可能带来的问题。

额外排查步骤

如果修复后仍有乱码,建议做以下验证:

  1. 抓包确认设备发送的实际数据:用Wireshark抓取设备到服务器的TCP包,查看原始二进制数据是否符合UTF-8编码的JSON格式,是否有额外的前缀/后缀字节。
  2. 测试设备的编码格式:有些设备可能标注UTF-8但实际用GBK等其他编码,可以尝试用buffer.toString('gbk')(需要安装iconv-lite库)测试解析。
  3. 检查设备的发送协议:确认设备是否用特定的分隔符(比如\r\n)分隔每条JSON数据,如果有,代码可以按分隔符拆分Buffer,避免解析不完整的问题。

内容的提问来源于stack exchange,提问作者Ani

火山引擎 最新活动