【问题标题】:Can't listen on multiple sockets when using BINDTODEVICE?使用 BINDTODEVICE 时无法监听多个套接字?
【发布时间】:2014-01-19 23:30:18
【问题描述】:

我有两个到 Internet 的网络链接,并且我设置了两个默认路由:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway0        0.0.0.0         UG    0      0      eth0
default         gateway1        0.0.0.0         UG    0      0      eth1
...

我使用 BINDTODEVICE 创建了两个套接字,以便我可以将数据发送到 eth0 或 eth1。我还尝试使用recvfrom(仅限UDP数据)监听两个套接字,但我只能从路由中首先列出的任何接口成功读取数据。例如,eth0 有效,但我从绑定到eth1 的套接字中什么也得不到。

在任一接口上运行 wireshark 都显示数据成功进入 - 也就是说,我可以看到数据从 Internet 发送到 Wireshark 中的 eth0 或 eth1 的 IP(因此 NAT 都不是问题),但我的程序只是阻塞在recvfrom 上没有得到任何数据。

我尝试在套接字上使用bind 让它们监听各自接口的 IP,还尝试不使用 bind 让它们监听 0.0.0.0(每个端口都在不同的端口),但我仍然有同样的问题。

我怎样才能确保两个套接字都得到它们应该得到的数据?

编辑:示例代码:

int createDeviceBoundUDPSocket(uint32_t sip, uint16_t sport, const char* bind_dev) {
    printf("bind_dev = %s", bind_dev);
   int s = socket(AF_INET, SOCK_DGRAM, 0);   
   int result;
   struct sockaddr_in my_ip_addr;

   if (s < 0) {
      perror("socket");
      return s;
   }

   memset(&my_ip_addr, 0, sizeof(my_ip_addr));

   my_ip_addr.sin_family = AF_INET;
   my_ip_addr.sin_addr.s_addr = htonl(sip);
   my_ip_addr.sin_port = htons(sport);

   // commenting this section out doesn't seem to make a difference
   // listening on 0.0.0.0 or the interface's IP both have the same problem
   result = bind(s, (struct sockaddr*)(&my_ip_addr), sizeof(my_ip_addr));
   if (result < 0) {
      perror("Error in bind");
      return result;
   }

   if (bind_dev) {
      // Bind to specific device.
      if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
                     bind_dev, strlen(bind_dev) + 1)) {
         perror("Error binding to device");
         return -1;
      }
   }

   return s;
}

【问题讨论】:

  • 请出示您的实际代码。您可能没有正确设置绑定。
  • 绑定用于发送数据,对于一个接口,用于接收数据。所以我目前不怀疑那部分。
  • 不要混用 bind()SO_BINDTODEVICE。使用其中一种。通常,您应该使用bind()
  • 两者都试过了——上面写着...

标签: sockets unix udp recvfrom


【解决方案1】:

正如the Linux Advanced Routing and Traffic Control 指南所暗示的,解决方案是关闭反向路径过滤。不确定三个接口中的哪一个需要关闭它,但正在做

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

成功了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多