3

I am using node.js to build a tcp server, and I want to extract integers from the data received.

var net = require('net');
var server = net.createServer(function (socket) {
  socket.setEncoding('ascii');
  socket.addListener("data", function (data) {
    var pkgDataContent = data.substr(0, 2);
  });
});
server.listen(1337, "192.168.80.91");

The data received is string type, and the numbers are 1 byte, 2 bytes and 4 bytes. How to extract these 1-byte, 2-byte and 4-byte integers from a javascript string? Like the code above: pkgDataContent is a string of 2 bytes, but actually it is an integer, how to convert it to javascript number correctly?

Mickey Shine
  • 12,187
  • 25
  • 96
  • 148
  • Isn't ascii 1-byte per char? In that case, can't you just use `pkgDataContent.charCodeAt(0)`? – Alxandr May 18 '11 at 01:41
  • 1
    http://stackoverflow.com/questions/1240408/reading-bytes-from-a-javascript-string might help – Rasika May 18 '11 at 01:48
  • Are you sure your example code is correct? You appear to add two 'data' listeners when one will suffice and you're missing a '})'. – Rob Raisch May 18 '11 at 01:50
  • And if the data starts with either a one, two or four byte integer, how do you differentiate between them? Is the value delimited in some way? – Rob Raisch May 18 '11 at 01:52
  • @Rob Raisch, thank you for pointing out the mistakes, I've corrected them. The stream is of exact format so it is possible to extract integers with conventions. – Mickey Shine May 18 '11 at 01:59
  • @Rasika, that may be for javascript within a browser. I am using node.js, so I am not sure if the environment is different – Mickey Shine May 18 '11 at 02:00
  • "extract integers with conventions"? Do you mean that a packet of exactly one byte will represent an integer between 0 and 255, a packet of exactly two bytes represents an int from 0 to 65,535, etc.? – Rob Raisch May 18 '11 at 02:19

2 Answers2

4

Depends on endianness and on whether it's signed or not.

big endian 32-bit unsigned integer:

pkgDataContent.charCodeAt(0) << (8*3) +
pkgDataContent.charCodeAt(1) << (8*2) +
pkgDataContent.charCodeAt(2) << (8*1) +
pkgDataContent.charCodeAt(3) << (8*0)

little endian 32-bit unsigned integer:

pkgDataContent.charCodeAt(3) << (8*0) +
pkgDataContent.charCodeAt(2) << (8*1) +
pkgDataContent.charCodeAt(1) << (8*2) +
pkgDataContent.charCodeAt(0) << (8*3)
ikegami
  • 367,544
  • 15
  • 269
  • 518
3

The 'data' passed in your function is Buffer object. it can contain any binary data. Suppose that a received packet is the plain c structure like this,

typedef struct _SOME_PACKET
{
    unsigned short nLen; //2byte
    char szSomeMSg [16];    
} SOME_PACKET;

then the first 2 byte of data is binary data. and you can get the integer by Buffer's method.

var littleEndianInt = data.readUInt16LE(0); 
//or
var bigEndianInt    = data.readUInt16BE(0);

To get the rest data after 2 bytes, you can use offset.

var restOfDataExceptInt = new Buffer( data.length - 2 ); 
restOfDataExceptInt.fill();
data.copy( restOfDataExceptInt, 0, 2, data.length  );

which endian to use? it depends on which endian your computer use.

[little-endian system]

  • Linux on x86, x64, Alpha and Itanium
  • Mac OS X on x86, x64
  • OpenVMS on VAX, Alpha and Itanium
  • Solaris on x86, x64, PowerPC
  • Tru64 UNIX on Alpha
  • Windows on x86, x64 and Itanium

[big-endian system]

  • AIX on POWER
  • AmigaOS on PowerPC and 680x0
  • HP-UX on Itanium and PA-RISC
  • Linux on MIPS, SPARC, PA-RISC, POWER, PowerPC, 680x0, ESA/390, and z/Architecture
  • Mac OS on PowerPC and 680x0
  • Mac OS X on PowerPC
  • MVS and DOS/VSE on ESA/390, and z/VSE and z/OS on z/Architecture
  • Solaris on SPARC

also please refer to this:

https://github.com/jeremyko/nodeChatServer

Hope this help.

jeremyko
  • 408
  • 5
  • 8