node.jsudposcdgrams

Fixed port for sending messages with dgram


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();
    });
  });
});

Solution

  • 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.