Привязать сокет UDP к определенному сетевому интерфейсу, используя Boost.Asio - PullRequest
2 голосов
/ 15 апреля 2019

На моем ПК установлено несколько сетевых карт, и я пытаюсь получить данные UDP от нескольких широковещательных устройств. Каждое устройство изолировано в выделенной сети, и я пытаюсь считывать данные UDP с нескольких устройств одновременно. Я использую Boost версии 1.67. Давайте представим в этом посте, что я хочу получать данные только от одного конкретного устройства, поэтому я хочу привязать его к локальному сетевому интерфейсу.

В Windows работает следующий код, но на моей 64-битной машине с Ubuntu 16.04 это не так. Действительно, если я связываюсь с одним конкретным локальным IP-адресом (192.168.1.1 в этом примере), я не получаю никаких данных. Но если я использую ЛЮБОЙ адрес «0.0.0.0», я получаю то, что хочу. За исключением того, что в этом случае я не знаю, откуда это. Его можно получить любой сетевой картой!

Это нормальное поведение? Или мне нужно прочитать sender_endpoint, чтобы узнать эту информацию о Linux и затем отфильтровать?

#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>

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

int main(int argc, char* argv[])
{
  try
  {
    boost::asio::io_context io_context;

    // Setup UDP Socket
    udp::socket socket(io_context);
    socket.open(udp::v4());

    // Bind to specific network card and chosen port
    socket.bind(udp::endpoint(boost::asio::ip::address::from_string("192.168.1.1"), 2368));

    // Prepare to receive data
    boost::array<char, 128> recv_buf;
    udp::endpoint sender_endpoint;
    size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);

    // Write data to std output
    std::cout.write(recv_buf.data(), len);
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
...