net socket 接收客户端tcp数据出错(已解决)
发布于 5个月前 作者 Lishaojun 660 次浏览

var server = net.createServer(function (sock) { var dataBuff = new Buffer(512); var dataBuffLength = 0; sock.setTimeout(SocketTimeOut); sock.setEncoding(‘ascii’); sock.on('readable’, function() { var g_count = 0; var i_length = 0; var chunk = '’; while (null !== (chunk = sock.read())) { dataBuffLength += dataBuff.write(chunk, dataBuffLength, chunk.length); } console.log(“dataBuff:” + dataBuff.length); console.log(“dataBuffLength:” + dataBuffLength); console.log(dataBuff); }); }); 上面是tcp socket服务器接收代码。

dataBuff里面的16进制数据应该是: 00 02 AD 00 01 05 65 73 30 30 31 02 0C 71 77 65 72 41 53 44 46 31 32 33 34 03 06 32 30 30 33 35 36 32 11 00(这段数据我是通过网络调试助手捕捉的是我想要的数据)

但是经过上面接收代码处理变成: 00 02 2D 00 01 05 65 73 30 30 31 02 0C 71 77 65 72 41 53 44 46 31 32 33 34 03 06 32 30 30 33 35 36 32 11 00

这个问题折腾3天了,sock.setEncoding(‘ascii’);中编码全部换过都得不到我想要的数据,求前辈指点一二啊。 客户端是通过GPRS socket发送过来的数据。

25 回复

为什么使用readable事件,而不是data事件。 加上ascii表示将每个字节当作ascii字符来看,你确定发来的数据是按字符来看?还是若干字节表示一个数值? 另外三个字节不科学啊,TCP有错误重传机制,不可能发送的时候和接收到的不一致的情况。

@nodejser 我试过readable和data两个事件效果一样的,客户端发过来数据应该用二进制的,而且用C代码数据和的数据,类似byte类型数据8位二进制数据全部都需要的。 另外readable比data相应速度少一个步骤(个人分析,如错误请纠正)。

@Lishaojun 你可以把协议的内容先用调试助手发往node,看看结果如何。

@nodejser 如果用utf8编码,得到数据是00 02 ef bf bd 00 01 05 65 73 30 30 31 02 0c 71 77 65 72 41 53 44 46 31 32 33 34 03 06 32 30 30 33 35 36 32 11 00,数据变得跟离谱。

@nodejser 我现在调试步骤,用调试助手捕捉客户端数据存文件,然后通过调试助手发送文件数据到node,得到就是上面结果。 如果调试助手(模拟客户端)发送调试助手(模拟服务端),数据收发正常的。

@nodejser 一段数据里面有uint8、uint16、uint32、字符串数据类型。

@Lishaojun 我觉得这是你的理解不正确,因为对于相同的文本来说,不同的编码方式必然产生的结果不同,在网络中传输时也就不同。 你得先确认发送给你的到底是文本还是纯粹的二进制数据。。。比方说收到 FF FF,如果当做一个数值来看也可以理解成16位的无符合整数65535,也可以看成两个单独的字节,也可以看成二个ascii字符。总之你得先了解协议。

@Lishaojun 引用“一段数据里面有uint8、uint16、uint32、字符串数据类型。” 这样的需求,你得先获取一帧完整的报文,然后按照协议,去分别读取uint8,uint16等等。

我确定不是文本,是二进制数据,开始怀疑调试助手发送文件数据会有偏差,后面我打开客户端发送真是数据到服务器,服务器开启node打印数据,情况一样的。 客户端的数据发送协议在java那边解析正常的,

@Lishaojun 那现在的问题是?

@nodejser node监听端口socket接收数据不对, java那边就正常,

@nodejser node只处理后台数据

把net换成socket.io试试,实在没办法了。

试试,这个不分析协议,仅将收到的数据追加后显示

‘use strict’

var net = require(‘net’); var config = { tcpPort: 5000 };

var srv = net.createServer(function © {

var data = [];

c.on('data', function (chunk) {
    
    data.push(chunk);
    console.log(data);

});

c.on('timeout', function () {
    console.log('timeout');
});

c.on('error', function (ex) {
    console.log('error');
});

c.on('close', function (had_error) {
    console.log('close')  ;
});

c.on('end', function () {
    console.log('end');
});

});

srv.on(‘error’, function (e) { if (e.code === ‘EADDRINUSE’) { console.log(config.tcpPort,’被占用’); } ; });

srv.listen(config.tcpPort, function () { console.log('在’,config.tcpPort + ‘运行’); });

@nodejser 按照你方法得到数据: [ ‘\u0000\u0002�\u0000\u0001\u0005es001\u0002\fqwerASDF1234\u0003\u00062003562\u 0011\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00 00\u0000\u0000\u0000\u00003\u00004\u0004��<A5\u0002�36\u0002�\u00007\u000433�A8
u000433�A9\u0001/:\u0004ff�B;\u0004\u0000\u0000\u0000\u0000<\u0002�5=\u0002�3>\u 0002�\u0000?\u0002�\u0000@\u0001\u0000A\u0004��\u0005CB\u0004\u0000\u0000\u0000
u0000C\b33333��@D\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000E\u0004\u0018 \u0000\u0000\u0000F\u0004\u0001\u0000\u0000\u0000G\u0004\u0000\u0000\u0000\u0000 H\u0004\u0000\u0000\u0000\u0000I\u0001\u0001’ ]

跟我的写法用utf8编码一样的结果

调试工具用二进制发。

@nodejser 调试工具只有16进制发送

16进制,我常说二进制。呵呵。

@nodejser 16进制发送,console.log(data);数据空白,在cmd看不见,

@Lishaojun 你确定你发送的端口号正确? 你确定你使用的工具创建的是tcp客户端?

如果都对,那就换个工具吧。

@nodejser 呵呵,确定的,我刚才用socket.io又失败,操作不起来。换工具的话,我直接用终端客户端直接发真实数据好了。

@nodejser真实数据测试结果一样的,头快炸了,

sock.setEncoding(‘hex’);

dataBuffLength += dataBuff.write(chunk, dataBuffLength, chunk.length,’hex’);

@chrome10086 膜拜,大神,真的可以了。小弟受教了。

回到顶部