使用Boost.Asio将UDP套接字绑定到特定的网络接口

时间:2019-04-15 08:16:44

标签: c++ sockets boost boost-asio

我的PC有多个网卡,并且我正尝试从多个广播设备接收UDP数据。每个设备都隔离在专用网络上,我正在尝试同时从多个设备读取UDP数据。我正在使用Boost版本1.67。让我们在这篇文章中假装我想从一个唯一的特定设备获取数据,因此我想绑定在本地网络接口上。

在Windows上,以下代码有效,但在我的Ubuntu 16.04 64位计算机上则无效。确实,如果我绑定到一个特定的本地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;
}

1 个答案:

答案 0 :(得分:0)

有点晚了,但其他人可能会想到这一点,因为我一直在用 Boost 尝试这个,并试图弄清楚它是如何工作的。通过查看这个问题:Fail to listen to UDP Port with boost::asio 我去了这个页面:https://forums.codeguru.com/showthread.php?504427-boost-asio-receive-on-linux 并且在 Linux 上你需要绑定到“任何地址”才能接收广播数据包。因此,您可以将其设置为您的接收端点:

udp::endpoint(boost::asio::ip::address_v4::any(), port)

然后是的,您需要过滤发件人信息。看起来有点奇怪,但似乎是 Linux 接口处理广播的方式。