Исправлен порт для отправки сообщений с помощью dgram

Я использую node dgram для отправки сообщений OSC на устройство. Устройство отправляет свои ответы на порт, откуда пришел запрос (я не могу это изменить).

Теперь моя проблема заключается в том, что я не знаю, какой порт dgram будет использовать для отправки сообщения, поэтому я не могу привязать сокет UDP для прослушивания правильного порта для ответа.

Есть ли способ заставить dgram каждый раз отправлять с заранее определенного порта?

Изменить: добавлен код

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

person cracanut    schedule 16.06.2019    source источник
comment
Прежде чем публиковать вопрос, просмотрите stackoverflow.com/help/how-to-ask. Совместное использование кода, который вы пробовали, будет более полезным для людей, пытающихся вам помочь. Спасибо   -  person sureshprasanna70    schedule 16.06.2019


Ответы (1)


Есть ли способ заставить dgram каждый раз отправлять с заранее определенного порта?

Просто привяжите сокет UDP к порту (и IP), который вы хотите использовать в качестве исходного порта. Когда вы затем вызовете send или sendto для этого сокета, он будет использовать адрес (IP+порт), к которому вы привязаны, в качестве исходного адреса. Затем вы можете вызвать recv или recvfrom в том же сокете, чтобы получить ответ.

РЕДАКТИРОВАТЬ - после просмотра фактического кода:
проблема в том, что вы создали другой сокет UDP для отправки. Вместо этого вы должны использовать сокет, который уже привязан к адресу и порту, не только для приема, но и для отправки.

person Steffen Ullrich    schedule 16.06.2019
comment
Я пытался привязать порт, однако, похоже, это влияет только на принимающий порт. - person cracanut; 16.06.2019
comment
@cracanut: тогда ты сделал что-то не так. Только, поскольку вы не предоставляете ни код, ни то, как вы тестировали, и какие именно результаты вы получили, невозможно выяснить, что именно вы сделали неправильно. - person Steffen Ullrich; 16.06.2019
comment
Я отредактировал свой исходный вопрос, включив в него код, который я использую. Как видите, я уже делаю привязку, но это влияет только на порт «прослушивания». Я предполагаю, что мне, возможно, придется использовать альтернативу dgram? - person cracanut; 18.06.2019
comment
@cracanut: UDP не имеет концепции прослушивающего сокета и подключенного сокета, как TCP, потому что в UDP нет такого понятия, как установление соединения - есть только отправка дейтаграмм. Это означает, что вы должны использовать сокет прослушивания для отправки данных, и в этом случае они будут отправлены с правильным исходным адресом и портом. - person Steffen Ullrich; 18.06.2019
comment
Спасибо, я совершенно упустил из виду создание второго сокета UDP внизу. Я изменил отправку, чтобы также использовать UDPServer, и теперь он работает, как и ожидалось. Это то, что вы получаете за копирование в Интернете, я думаю :) - person cracanut; 18.06.2019
comment
Еще один момент, можно ли пометить комментарий как правильный ответ или просто пост в целом? - person cracanut; 18.06.2019
comment
@cracanut: Насколько я вижу, только ответ может быть помечен как правильный. Но я добавил суть из комментария в ответ. - person Steffen Ullrich; 18.06.2019