ar2015 ar2015 - 3 months ago 15
Node.js Question

NodeJs receive UDP numbers in ugly binary format

I have no knowledge in

node.js
.

After my previous question about how to send
UDP
string text with
C++
and receive it from
Node.js
, I am thinking about receiving numbers (and even more generally, receiving objects).

The results I get are ugly characters with binary format. How should I fix them?

Results:

127.0.0.1:1414 - (�@
127.0.0.1:1414 - ףp=
(�@
127.0.0.1:1414 - �G�z(�@
127.0.0.1:1414 - ��Q�(�@
127.0.0.1:1414 - \���((�@
127.0.0.1:1414 - 33333(�@
127.0.0.1:1414 -
ףp=(�@
127.0.0.1:1414 - �z�G(�@
127.0.0.1:1414 - ���Q(�@
127.0.0.1:1414 - ���(\(�@
127.0.0.1:1414 - gffff(�@
127.0.0.1:1414 - >
ףp(�@
127.0.0.1:1414 - �G�z(�@
127.0.0.1:1414 - �Q��(�@
127.0.0.1:1414 - ��(\�(�@
127.0.0.1:1414 - �����(�@
127.0.0.1:1414 - q=
ף(�@
127.0.0.1:1414 - H�z�(�@
127.0.0.1:1414 - ��Q�(�@
127.0.0.1:1414 - �(\��(�@
127.0.0.1:1414 - �����(�@
127.0.0.1:1414 - �p=
�(�@
127.0.0.1:1414 - {�G�(�@
127.0.0.1:1414 - R���(�@
127.0.0.1:1414 - )\���(�@
127.0.0.1:1414 - )�@
127.0.0.1:1414 - ףp=
)�@
127.0.0.1:1414 - �G�z)�@
127.0.0.1:1414 - ��Q�)�@
127.0.0.1:1414 - \���()�@
127.0.0.1:1414 - 33333)�@
127.0.0.1:1414 -


app.js

var PORT = 1414;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var server = dgram.createSocket({ type: 'udp4', reuseAddr: true });

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(remote.address + ':' + remote.port +' - ' + message);

});

server.bind(PORT, HOST);


main.cpp

// g++ main.cpp -o main -std=c++11 -lboost_system -pthread

#include <iostream>
#include <stdio.h>
#include <string>
#include <boost/asio.hpp>

using boost::asio::ip::udp;


int main(int argc, char* argv[])
{

const int port=1414;
const std::string ip="127.0.0.1";

boost::asio::io_service io_service;
udp::resolver resolver(io_service);

udp::endpoint client_endpoint = *resolver.resolve({udp::v4(), ip, std::to_string(port)});
udp::socket socket(io_service, udp::v4());
socket.set_option(boost::asio::socket_base::reuse_address(true));
socket.bind(udp::endpoint(udp::v4(), port));

double data;
for(long i=0;true;i++)
{
data=i*0.01;
socket.send_to(boost::asio::buffer((char *)&data, sizeof(data)), client_endpoint);
usleep(10);
}

return 0;
}

Answer

What you are receiving are Buffers, which contain binary data. By concatenating message with a string, you are implicitly calling message.toString() which by default will convert the binary data to UTF8, which is what you are seeing.

Instead what you will need to do is read directly from message. You can read numbers from a Buffer using the message.read*() methods.

There is a problem you will still encounter with your current code however: the order in which your data bytes are being sent is dependent upon the host's CPU (type). It's best to send data over a network in network byte order (big endian) to ensure compatibility and consistency.

Assuming however you are running on say a typical Intel or AMD CPU, you should be able to use message.readDoubleLE() on the node.js side to read the value.

Comments