Node.js UDP client to handle a response from a udp server - node.js

I am trying to write an app in node.js to send a udp request to a device ( which has udp server) and then receive the response and display it. The device acts in such a way that upon receipt of a request on its port 11220 it returns a response immediately.
The code below sends a udp request to the device and the device responses back immediately ( I can see it in wireshark) but I can not handle/display the revived message. Or at least I just want to be able to display a message upon receipt of a reply from the device. Please let me know what is missing in my code or show me a complete code to do it. Very much appreciated.
As well, I do not prefer to use socket.io etc.
var PORT = 11220 ;
var HOST = '192.168.1.111';
var dgram = require('dgram');
var message = new Buffer(9);
var client = dgram.createSocket('udp4');
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log('UDP message sent to ' + HOST +':'+ PORT);
client.close();
});
client.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, remote) {
// CAN I HANDLE THE RECIVED REPLY HERE????
console.log(remote.address + ':' + remote.port +' - ' + message);
});

Just stumbled across the question so I thought I'd pipe in with an answer:
In your client.send function, calling client.close(); will close the UDP connection between your server and the client. Therefore, if you want to listen for messages, you should not call that immediately after you send your message.
Secondly, loganfsmyth's comment provided some good advice - you should add your event handlers first, then send the message.
In the end, this was the changed code needed to get your scenario working
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);
});
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log('UDP message sent to ' + HOST +':'+ PORT);
});

Related

Why does the server respond iteratively with each new piece of input data I send it from the console?

I am just trying to learn some client-server basics and I'm almost there with what I'm trying to do. I am just sending the server some input and having it respond back to the client with the data it received. However, it works fine once I send the first piece of data but once I send another input the server responds with two instances of that same piece of data, and so on. How do I get around this?
Server:
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var server = net.createServer();
server.on('connection', function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress +':' + data);
// write back data received to the client
sock.write('You said "' + data + '"');
});
});
server.listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
Client:
var net = require('net');
var readline = require('readline');
var HOST = '127.0.0.1';
var PORT = 6969;
const r1 = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// continue talkback
function waitForUserInput() {
r1.question("Enter some data you wish to send: ", function(data) {
if(data == "exit") {
r1.close();
} else {
// write input data to the server
client.write(data);
// receive what data server sends back to client
client.on('data', function(server_data) {
console.log('DATA: ' + server_data);
});
setInterval(waitForUserInput, 1000);
}
});
}
waitForUserInput();
});
You keep adding more and more client.on('data', ...) handlers. Each time you call waitForUserInput(), you end up adding another duplicate handler for the data message. So, after calling waitForUserInput() twice, you have two identical handlers for the data message so when a new piece of data arrives, each of the two handlers gets called and the output in your console appears twice. One one piece of data arrives, but you have duplicate handlers that are listening for it.
You can either use .once() instead of .one() or you can move the handler listening for the incoming data outside of the function so it's just installed once and only once.
Incidentally, using setInterval() here is also a problem for several reasons. You're creating a new interval timer every time you call waitForUserInput() and there's no coordination between that and when the question is actually answered.

Node JS: UDP Client does not work in OSX (11.2.2)

I have a windows machine running a udp-server and I try to create a UDP->WebSocket Bridge using node-js...
But I just came as far as connection to the server which seems to run nice on windows but fails on osx.
Using this code:
var PORT = 8005;
var HOST = '192.168.1.33';
var dgram = require('dgram');
var message = new Buffer.from('CONNECTED');
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);
});
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log('UDP message sent to ' + HOST +':'+ PORT);
});
Windows outputs nice:
UDP Server listening on 0.0.0.0:65054
UDP message sent to 192.168.36.1:8005
192.168.36.33:8005 - OK
OSX Just:
UDP Server listening on 0.0.0.0:50360
UDP message sent to 192.168.36.1:8005
The Windows server reports a socket error which normaly means there is a network-issue.
I wonder where the problem is, looks like OSX blocks the udp-connection for some reason but I have no firewall or other filter activated or installed on my mac.
Any idea?
Seems the problem is solved, when I disable Wifi and just use my ethernet connection. Seems to be an issue when two network interface are available. Maybe it sends out on device1 but listens on device2...

Node.js Socket pipe last packet

I have Node server ,This server creates a tcp socket connection with other side TCP server. I'm trying to pipe tcp data but when i was received a message for second time i got both the new message and the previous one(the first one) in the same stream. How can i fix this?
var net = require('net');
var HOST = '127.0.0.1'; // parameterize the IP of the Listen
var PORT = 6969; // TCP LISTEN port
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function(data) {
sock.write(data);
socket.pipe(socket);
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
}).listen(PORT, HOST);
I'm assuming you want to create an echo server.
So you have two options - either piping:
// [...]
net.createServer(function(sock) {
sock.pipe(sock);
}
// [...]
Or you subscribe data and manually write to the socket (which is the same as pipe)
// [...]
net.createServer(function(sock) {
sock.on('data', function(data) {
sock.write(data);
});
}
// [...]
With your current program, when someone sends data the first time you echo the data but also create a pipe connection which means next time the data is sent twice (as you described).

Node.js - "Rebind" UDP socket server to a new port

Which is the most efficient way to change a UDP server's listening port on runtime on Node.js?
I have a default port 41234 for my web app but I want the end-user to be able to change this through a settings textbox, which would call the updatePort().
Using the following code the new (neither the old) port isn't actually listening for datagrams, as I cant receive anything.
var SRV_PORT = 41234;
var server = dgram.createSocket("udp4");
server.on("error", function (err) {
print("server error:\n" + err.stack);
server.close();
});
server.on("message", function (msg, rinfo) {
//code for incoming datagram analysis here
});
server.on("listening", function () {
var address = server.address();
print("server listening " + address.address + ":" + address.port);
});
//start the UDP server with the default SRV_PORT
server.bind(SRV_PORT);
function updatePort(newPort) {
server.close();
server = dgram.createSocket("udp4");
server.bind(newPort);
}
The reason you wouldn't get any messages after updating the port is because you've assigned a new socket instance to server and do not have any event handlers attached anymore.

node.js listen for UDP and forward to connected http web clients

I'm new to node.js, so forgive the ignorance if this is simple.
What I want to do is setup a simple node.js http server to which a web-client connects. I also want the node.js server to act as a UDP listener on a separate port, on which it will receive JSON payloads from some other application. I want the node.js server to then forward these JSON payloads immediately to one or more of the connected web-clients.
I got this far from some initial googling around:
Create a simple node.js http server that responds with a static html page:
//Initialize the HTTP server on port 8080, serve the index.html page
var server = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: 127.0.0.1 8080');
}
);
Initialize a UDP server on a separate port:
//Initialize a UDP server to listen for json payloads on port 3333
var srv = dgram.createSocket("udp4");
srv.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " + rinfo.address + ":" + rinfo.port);
io.sockets.broadcast.emit('message', 'test');
//stream.write(msg);
//socket.broadcast.emit('message',msg);
});
srv.on("listening", function () {
var address = srv.address();
console.log("server listening " + address.address + ":" + address.port);
});
srv.bind(5555);
Use socket.io to establish a live connection between web-client and server:
//this listens for socket messages from the client and broadcasts to all other clients
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg.data.skeletons[0] ? msg.data.skeletons[0].skeleton_id : '');
socket.broadcast.emit('message', msg);
}
);
});
I guess my problem is I don't know how to bridge 2 and 3, to get the received UDP packets broadcasted to the connected socket.io clients. Or perhaps there's a simpler, more elegant way of doing this? I found the documentation for socket.io to be lacking...
EDIT: thanks to the person that fixed the code formatting
I made a running example for you to get going with: http://runnable.com/UXsar5hEezgaAACJ
For now it's just a loopback client -> socket.io -> udp client -> udp server -> socket.io - > client.
here's the core of it:
var http = require('http');
var fs = require('fs');
var html = fs.readFileSync(__dirname + '/index.html');
//Initialize the HTTP server on port 8080, serve the index.html page
var server = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-type': 'text/html'
});
res.end(html);
}).listen( process.env.OPENSHIFT_NODEJS_PORT, process.env.OPENSHIFT_NODEJS_IP, function() {
console.log('Listening');
});
var io = require('socket.io').listen(server);
io.set('log level', 0);
io.sockets.on('connection', function (socket) {
socket.emit('message', 'connected');
socket.on('message', function (data) {
console.log(data);
var address = srv.address();
var client = dgram.createSocket("udp4");
var message = new Buffer(data);
client.send(message, 0, message.length, address.port, address.address, function(err, bytes) {
client.close();
});
});
});
var dgram = require('dgram');
//Initialize a UDP server to listen for json payloads on port 3333
var srv = dgram.createSocket("udp4");
srv.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " + rinfo.address + ":" + rinfo.port);
io.sockets.emit('message', 'udp');
});
srv.on("listening", function () {
var address = srv.address();
console.log("server listening " + address.address + ":" + address.port);
});
srv.on('error', function (err) {
console.error(err);
process.exit(0);
});
srv.bind();

Resources