如何通过本地大于1500字节的UDP数据包发送浮动并解析它们

时间:2016-01-09 14:42:11

标签: javascript node.js sockets udp buffer

我试图通过UDP发送一个非常大的浮点数组。我正在使用浮点并且不太确定如何将这些解析回服务器上的原始状态。服务器和客户端将在两个应用程序之间本地运行。而服务器将转换为C#应用程序。

客户:

var PORT = 33333;
var HOST = '127.0.0.1';

var dgram = require('dgram');
_data =[-28.5686,97.3002,142.458,0.440512,2.45745,-0.144664,-0.17135,-18.0888,-0.507999,1.4921e-021,3.27051e-018,-0.0534133,-0.000146994,33.8001,0.463196,4.90246e-021,5.86576e-018,-0.0957984,2.09062,-14.5077,0.266143,-4.29059e-007,-1.04696e-007,-7.84019e-016,-4.04058,-15.1361,-3.75471,6.63063e-020,2.15707e-017,-0.352291,7.47538e-005,29.8537,5.90907,3.48822e-023,-4.28574e-019,0.00699938,1.40942,-15.474,0.186975,0.0293333,-0.019122,4.3858e-005,0.01778,-0.263464,0.123309,-0.196127,0.018499,0.0899181,-0.193886,0.0187146,0.0906704,-0.193708,0.0189286,0.0912595,-12.7908,0,-7.41445,-51.7233,9.71027,-4.09645,-0,1.34465,0,42.7628,43.1268,-53.5281,-0,0.542484,0,-15.8093,1.1398,-8.18984,-11.3353,5.42235,10.9137,-30.5178,-1.01592,1.72285,-26.2457,0,0,-0,0,0,-29.8264,-0.995051,0.607773,-112.753,0,0,-53.037,0,0,-0,0,0,-33.1392,-1.09366,5.26616,-111.292,0,0,-50.936,0,0,-0,0,0,-32.1005,-1.06312,0.623497,-103.333,0,0,-43.6037,0,0,-0,0,0,-5.9451,-0.207234,4.09042,-96.4444,0,0,-38.244,0,0,-0,0,0,19.4098,9.98358e-016,10.5068,50.3766,4.8873,2.22908,3.1563e-016,2.57567,-7.09555e-018,-36.3347,40.6501,48.4687,-7.43586e-006,0.592876,-2.70893e-006,16.9705,-0.244893,-1.64202,11.331,5.42212,-10.9131,29.2193,-0.97661,-1.74543,24.8369,0,0,0,0,-0,29.7912,-0.993986,-0.605762,112.622,0,0,52.9584,0,0,0,0,-0,33.0111,-1.08992,-3.26718,111.073,0,0,51.0729,0,0,0,0,-0,32.4514,-1.07348,1.33472,102.94,0,0,43.1189,0,0,0,0,-0,5.87599,-0.204834,-2.10028,96.0519,0,0,38.4021,0,0,0,0,-0,-2.97445,-2.05615,0.876116,5.61002,-7.05385,-0.893018];

var client = dgram.createSocket('udp4');
const buf = new Buffer(_data);

  client.send(buf, 0, buf.length, PORT, HOST, function(err, bytes) {
    if (err) throw err;
    console.log('UDP message sent to ' + HOST +':'+ PORT);
    client.close();
});

服务器:

var PORT = 33333;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var server = dgram.createSocket('udp4');

server.on('listening', function () {
    var address = server.address();
    console.log('UDP Server listening on ' + address.address + ":" + address.port);
});

server.on('message', function (message, remote) {
    console.log(message.length);

});

server.bind(PORT, HOST);

1 个答案:

答案 0 :(得分:1)

所以这里有一种方法可以将Buffer的{​​{1}}包装成TypedArray

var ta = new Float32Array(_data);
var buffer = new Buffer(ta.buffer);

TypedArray是Javascript的新增内容,因此您的节点版本可能不支持它们。这是让他们进入Buffer的另一种方式:

var buffer = new Buffer(_data.length * 4);
_data.forEach(function(float, index){
    buffer.writeFloatLE(float, index*4);
});

现在,您可以在服务器上阅读它们。从NodeJS服务器,您可以这样读取它们:

server.on('message', function (message, remote) {
    console.log(message.length);
    var arr = [];
    for(var i = 0; i < message.length; i+=4){
        arr.push(message.readFloatLE(i));
    }
    //arr = your array of floats.
});

关于UDP max size的问题,它取决于您网络的MTU,当然还取决于您使用的数据类型。 Doubles为8个字节,Floats为4个字节,Strings取决于您使用的编码。我使用_data对您的Floats进行了测试,它得到了864个字节,Doubles数据增长了两倍,并且使用字符串,它让我足够接近{{1} (但数据取决于数字的长度)。

如果您不想发送超过允许的数量,我认为您只有两个选项。您可以将其发送到块上或压缩它。

要压缩它,您可以使用Doubles生成zlib

buffer

然后在服务器上解压缩它:

var zlib = require('zlib');
zlib.deflate(buf, function(err, buf){ //deflate, gzip, etc
    client.send(buf, 0, buf.length, PORT, HOST, function(err, bytes) {
        if (err) throw err;
        console.log('UDP message sent to ' + HOST +':'+ PORT);
        client.close();
    });
});

我用var zlib = require('zlib'); server.on('message', function (message, remote) { console.log(message.length); zlib.inflate(message, function(err, message){ var arr = []; for(var i = 0; i < message.length; i+=4){ arr.push(message.readFloatLE(i)); } console.log(JSON.stringify(arr)); }); }); Floats减少了1/4(因此大约600字节)。我会玩其他压缩/解压缩方法,但请记住这里有性能价格。

如果要以块的形式发送,可以估算有效负载的大小。例如,如果您只想发送500个字节,那么您只能发送(500 -28)/ 4个元素(118)。所以你先拼接数组并先发送,然后再将它拼接成118个元素,直到剩下0个元素。

在其他数字类型(Int32,Floats,Doubles,BE,LE等)上查看Docs缓冲区方法。