I am trying to implement a communication protocol in JavaScript (language mandatory). The communication is done in TCP/IP thanks to webtcp.
Every packet is divided this way: content size in big endian + content
.
So for a packet of a size 28, let's say {"type": "success", "id": 0}
, the packet sent will be 0,0,0,28,'{','"', 't', etc...
.
I have no problem sending packets in pure JavaScript using this syntax.
The problem is, because of WebTCP, the packet I get on my end is always a string, and when the size of a packet is between 128 and 255 (I'm guessing, I just know that it is greater than 128), the size is read wrong. I think I know where the problem is:
Here is my function which extracts the data.
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
is a global variable which is filled every time data is received.
ntohl
is a function I got from http://blog.couchbase.com/starting-membase-nodejs (without the i
offset) which takes a 4 bytes array and returns an integer.
So the line at fault would be size.push(buffer.charCodeAt(idx));
, I'm guessing the charCodeAt
function overflows when the character code given is greater than an ASCII value (0-127). From printing on the server side (which works, I tried in python and C++), the size sent is 130, and on the JavaScript side, the size
array contains [0, 0, 0, 65533]
(or something like this, I don't remember the right number. With a size of 30 I get [0, 0, 0, 30]
so I know that this is supposed to work.
I have several questions :
- How can I extract the raw integer value of a char in a string ?
- Is there an easy way to turn the 4 first bytes into something like a bytearray ? Using only JS and jQuery.
Thanks.