- Home /
Trying to send binary 16bit ints over the web
I am trying to stream binary data from Node.js to Unity.
I need to send a large amount of binary data between these two systems.
This is the Node script (its javascript. REAL javascript.) var http = require('http');
var port = 8011; http.createServer( function (request, response) { var buf = require('neobuffer').Buffer(200, 'binary'); for (var i = 0; i < 10; ++i){ // var value = (i + 20) (i + 20); buf.writeInt16(i, i 2, 'big'); } response.writeHead(200, {'Content-Type': 'text/plain'}); console.log('output string', buf.toString('binary').length, ':', buf.toString('binary')); response.write(buf.toString('binary')); response.end(); for (var i = 0; i < buf.length -4; i += 4){ console.log('byte', i,'-', i + 3, ':', buf[i], buf[i + 1], buf [i + 2], buf[i + 3]); } }).listen(port);
console.log('Server running at http://127.0.0.1:' + port + '/');
Also - I have tried several different encoding options - ranges include 'binary', 'utf8', 'hex' and 'usc2'.
The NeoBuffer is my "port" of a newer buffer utility (5.x branch of node) into my stable (4.x branch of node). The important methods taken from
[https://github.com/joyent/node/blob/02699a3/lib/buffer.js][1]
is:
Buffer.prototype.writeInt16 = function(value, offset, endian) { var buffer = this;
assert.ok(value !== undefined && value !== null, 'missing value');
assert.ok(endian !== undefined && endian !== null, 'missing endian');
assert.ok(endian == 'big' || endian == 'little', 'bad endian value');
assert.ok(offset !== undefined && offset !== null, 'missing offset');
assert.ok(offset + 1 < buffer.length, 'Trying to read beyond buffer length');
verifsint(value, 0x7fff, -0xf000);
if (value >= 0) { buffer.writeUInt16(value, offset, endian); } else { buffer.writeUInt16(0xffff + value + 1, offset, endian); } };
Buffer.prototype.writeUInt16 = function(value, offset, endian) { var buffer = this;
assert.ok(value !== undefined && value !== null, 'missing value');
assert.ok(endian !== undefined && endian !== null, 'missing endian');
assert.ok(endian == 'big' || endian == 'little', 'bad endian value');
assert.ok(offset !== undefined && offset !== null, 'missing offset');
assert.ok(offset + 1 < buffer.length, 'trying to read beyond buffer length');
verifuint(value, 0xffff);
if (endian == 'big') { buffer[offset] = (value & 0xff00) >>> 8; buffer[offset + 1] = value & 0x00ff; } else { buffer[offset + 1] = (value & 0xff00) >>> 8; buffer[offset] = value & 0x00ff; } };
I am attempting to intercodet it with this bit of UnityScript:
function Start(){ var req = new WWW('http://localhost:8011'); yield req; Debug.Log('req.bytes.length: ' + req.bytes.length); Debug.Log(req.text);
var ints = '';
var i_val:int;
for (var i:int = 0; i < req.bytes.length/2; i += 2){
//var neg = i_val & 0x8000;
//if (neg) {
// i_val = (0xffff - i_val + 1) * -1;
// }
i_val = req.bytes[i]<< 8 | req.bytes[i + 1];
ints += i_val + ',';
if ((i > 0) && ((i % 8) == 6)) {
Debug.Log(ints);
ints = '';
}
}
Debug.Log(ints);
var byte_string = '';
var b_val:byte ;
for ( i = 0; i < req.bytes.length -4; i += 1){
//var neg = i_val & 0x8000;
//if (neg) {
// i_val = (0xffff - i_val + 1) * -1;
// }
b_val = req.bytes[i];
byte_string += b_val + ',';
if ((i > 0) && ((i % 4) == 3)) {
Debug.Log('bytes: ...' + i + ':' + byte_string);
byte_string = '';
}
}
Debug.Log('bytes: ' + byte_string);
}
static function readUInt16 (buffer: byte[], offset:int, endian) { var val:int = 0;
if (offset > buffer.length -2) { return 0; }
if (endian == 'big') { var byte_1 = buffer[offset] << 8; val |= buffer[offset + 1]; } else { val = buffer[offset]; val |= buffer[offset + 1] << 8; }
return val; };
static function readInt16 (buffer: byte[], offset:int, endian) { var neg;
val = readUInt16(buffer, offset, endian); neg = val & 0x8000; if (!neg) { return val; }
return (0xffff - val + 1) * -1; };
Not only do I not get the right ints out, I don't even see the same ints when I look from one sample to another!
Here is the node output for comparison:
output string 200 : 'uöf Àmi¾ øgÀöýIĶ¾$õ¹ìɾDm[KÉ¡Ø¥²A)î?~µ ¼7îÌ(PM¦ÜOµ6Ô-?¿°¡ ëNj7ôvରy,FÜkÌ!1cTVNyam3ñäÓRÕ5Dµ°[P°f!·FêbBBÙDÂ(,Û;Q«}mog%Y_©Ã c@½GÍnþ*Zþ¯Þí`j#õdeËé byte 0 - 3 : 0 0 0 1 byte 4 - 7 : 0 2 0 3 byte 8 - 11 : 0 4 0 5 byte 12 - 15 : 0 6 0 7 byte 16 - 19 : 0 8 0 9 byte 20 - 23 : 39 117 246 102 byte 24 - 27 : 10 192 28 109 byte 28 - 31 : 105 190 133 248 byte 32 - 35 : 103 192 246 253 byte 36 - 39 : 73 157 154 196 byte 40 - 43 : 182 190 36 27 byte 44 - 47 : 35 245 185 236 byte 48 - 51 : 173 46 201 190 byte 52 - 55 : 68 155 109 91 byte 56 - 59 : 75 201 161 30 byte 60 - 63 : 216 165 136 178 byte 64 - 67 : 65 5 41 238 byte 68 - 71 : 173 63 126 181 byte 72 - 75 : 9 130 188 55 byte 76 - 79 : 139 238 204 40 byte 80 - 83 : 80 77 166 157 byte 84 - 87 : 220 79 181 54 byte 88 - 91 : 212 45 157 63 byte 92 - 95 : 191 147 176 161 byte 96 - 99 : 10 235 78 0 byte 100 - 103 : 106 55 244 15 byte 104 - 107 : 118 224 172 141 byte 108 - 111 : 176 121 44 70 byte 112 - 115 : 6 220 107 204 byte 116 - 119 : 33 49 99 84 byte 120 - 123 : 86 1 78 132 byte 124 - 127 : 143 121 97 152 byte 128 - 131 : 109 51 241 228 byte 132 - 135 : 211 82 213 31 byte 136 - 139 : 53 68 181 176 byte 140 - 143 : 91 80 29 176 byte 144 - 147 : 102 33 183 70 byte 148 - 151 : 234 98 66 66 byte 152 - 155 : 217 129 68 194 byte 156 - 159 : 40 44 5 219 byte 160 - 163 : 59 146 81 219 byte 164 - 167 : 8 171 18 125 byte 168 - 171 : 109 111 103 136 byte 172 - 175 : 37 89 95 169 byte 176 - 179 : 195 10 99 64 byte 180 - 183 : 189 71 205 110 byte 184 - 187 : 254 42 90 254 byte 188 - 191 : 175 222 237 96 byte 192 - 195 : 106 35 245 100Any suggestions?
Answer by DaveA · Oct 19, 2011 at 07:34 PM
I use System.Net.Sockets and "RedCorona.Net" (google that)
Answer by bingomanatee · Feb 12, 2012 at 05:37 PM
The trick to this - and I am doing pretty much the same thing in node - is to write the buffer straight to the response. (I am using express, so using the req/res paradigm, but I am sure the answer is the same in core http).
in node:
var b = new Buffer;
.... fill buffer...
res.write(buffer);
res.end();
in unity:
var w = new WWW('my/url');
yield w;
var b: byte[] = w.bytes;
If you use ANY encoding it screws with the byte stream - and you don't want encoded bytes, you want straight bytes.
the bad news: haven't quite figured out how to do the round trip....
Your answer
Follow this Question
Related Questions
Debugging Byte? 2 Answers
Max String Length in WWW url's? 1 Answer
Serializing an Action as XML? 0 Answers
seperate binary retrieved from sql server 1 Answer
wwwform send an array the right way! 0 Answers