我正在尝试用JavaScript实现通信协议(强制语言)。由于webtcp,通过TCP / IP完成通信。
每个数据包都以这种方式划分:content size in big endian + content
。
因此,对于大小为28的数据包,假设为{"type": "success", "id": 0}
,发送的数据包将为0,0,0,28,'{','"', 't', etc...
。
使用这种语法在纯JavaScript中发送数据包没有问题。
问题是,由于WebTCP,我得到的数据包总是一个字符串,当数据包的大小在128到255之间时(我猜,我只知道它大于128) ),大小读错了。我想我知道问题所在:
这是我提取数据的功能。
function extractData() {
// return empty string if not enough bytes to read the size of next packet
if (!buffer || buffer.length < 4) { return ""; }
// read size
var size = [];
for (var idx = 0 ; idx < 4 ; ++idx) {
size.push(buffer.charCodeAt(idx)); // pretty sure the problem comes from here.
}
// size from big endian to machine endian
size = ntohl(size);
// return empty string if the buffer does not have the complete packet yet
if (buffer.length < 4 + size) { return ""; }
// copy the packet content into ret
var ret = "";
for (var idx = 4 ; idx < size + 4 ; ++idx) {
ret += buffer[idx];
}
// the buffer removes the packet returned
buffer = buffer.substring(size + 4);
// return the packet content
return ret;
}
buffer
是一个全局变量,每次收到数据时都会填充。
ntohl
是我从http://blog.couchbase.com/starting-membase-nodejs得到的函数(没有i
偏移量),它接受一个4字节的数组并返回一个整数。
因此,故障线路为size.push(buffer.charCodeAt(idx));
,我猜测当给定的字符代码大于ASCII值(0-127)时,charCodeAt
函数会溢出。从服务器端的打印(有效,我尝试使用python和C ++),发送的大小为130,而在JavaScript方面,size
数组包含[0, 0, 0, 65533]
(或类似的东西,我不记得正确的号码。大小为30我得到[0, 0, 0, 30]
所以我知道这应该有效。
我有几个问题:
感谢。
答案 0 :(得分:0)
根据ntohl的定义,它除了一个整数和一个数组。
exports.ntohl = function(b, i) {
return ((0xff & b[i + 0]) << 24) |
((0xff & b[i + 1]) << 16) |
((0xff & b[i + 2]) << 8) |
((0xff & b[i + 3]));
}
其中b是数组,i是整数。
您只在代码示例中传递了一个参数。
如果我传递0,它会返回一个值,如果我没有传递参数,则返回0。
使用nthol(size,0)尝试你的代码;
这是一个证明这一点的小提琴:http://jsfiddle.net/3jxrr3k7/