0

I'm using node dgram to send OSC messages to a device. The device sends its responses to the port where the request came from (I can't change this).

Now my problem is that I don't know which port dgram will use to send the message, so I can't bind the UDP socket to listen to the correct port for the response.

Is there any way to force dgram to send from a pre-determined port everytime?

Edit: added code

var serverPorts = {
  ClientSide: 1488,
  ControllerSide: 1499
};

// UDP server, listens to controllers.
var dgram = require("dgram");
var UDPserver = dgram.createSocket("udp4");
const OSC = require("osc-js");
// socket.io, listening to K2
var SocketServer = require("socket.io").listen(serverPorts.ClientSide);

// Got messages on the server
UDPserver.on("message", function(msg, rinfo) {
  console.log(
    "server got: " + msg + " from " + rinfo.address + ":" + rinfo.port
  );
  // Send them to the K2 clients
  console.log("emitting on osc: " + msg);
  SocketServer.sockets.emit("osc", { osc: msg });
});

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

UDPserver.bind(serverPorts.ControllerSide);

SocketServer.sockets.on("connection", function(socket) {
  // Tell who we are and our version
  socket.emit("admin", { id: "K2OSCSERVER", version: 0.1 });
  console.log("Emitted ID and version on the admin channel");

  // K2 sent us OSC data
  socket.on("osc", function(data) {
    console.log("Received data on the 'osc' channel: " + data);
    // Send data on each one of the UDP hosts
    var message =
      typeof data.value != "undefined" && data.value != null
        ? new OSC.Message(data.path, data.value)
        : new OSC.Message(data.path);
    var binary = message.pack();
    var buffer = new Buffer.from(binary, "binary");
    var client = dgram.createSocket("udp4");
    client.send(buffer, 0, buffer.length, 10024, "192.168.0.171", function(
      err,
      bytes
    ) {
      console.log("err: ", err, "bytes: ", JSON.stringify(bytes));
      //client.close();
    });
  });
});
cracanut
  • 3
  • 2
  • Please go through https://stackoverflow.com/help/how-to-ask before posting the question. Sharing the code you have tried will be more helpful for people trying to help you. Thanks – sureshprasanna70 Jun 16 '19 at 17:26

1 Answers1

0

Is there any way to force dgram to send from a pre-determined port everytime?

Just bind the UDP socket to the port (and IP) you want to use as the source port. When you then call send or sendto on this socket it will use the address (IP+port) you've bound to as the source address. Then you can call recv or recvfrom on the same socket to get the response.

EDIT - after seeing the actual code:
the problem is that you've created another UDP socket for sending. Instead you should use the socket which is already bound on the address and port not only for receiving but also for sending.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • I did try to bind the port, however it only appears to be affecting the receiving port. – cracanut Jun 16 '19 at 19:46
  • @cracanut: then you did something wrong. Only, since you neither provide code nor how you've tested and what results you've got exactly it is impossible to find out what exactly you did wrong. – Steffen Ullrich Jun 16 '19 at 20:40
  • I've edited my original question to include the code I'm using. As you can see I'm already doing the binding but it only affects the 'listen' port. I'm guessing I might have to use a dgram alternative? – cracanut Jun 18 '19 at 16:08
  • @cracanut: UDP does not have the concept of a listening socket and a connected socket in the same way TCP does, because there is no such thing as a connection establishment in UDP - there is only sending of datagrams. This means you should use your "listen" socket to also send the data and in this case they will be sent with the proper source address and port. – Steffen Ullrich Jun 18 '19 at 16:19
  • Thanks, I totally overlooked the creation of the second UDP socket at the bottom. I changed the send to also use the UDPServer and now it works as expected. That's what you get for copy pasting of the internet I guess :) – cracanut Jun 18 '19 at 16:25
  • One more thing, is it possible to tag the comment as the correct answer or just the post in general? – cracanut Jun 18 '19 at 16:27
  • @cracanut: As far as I can see only the answer can be marked as correct. But I've added the essence from the comment to the answer. – Steffen Ullrich Jun 18 '19 at 17:59