【问题标题】:UDP Broadcast receive - Bind to several NIC'sUDP 广播接收 - 绑定到多个 NIC
【发布时间】:2014-10-20 23:45:32
【问题描述】:

我正在为 Linux 编写一个程序,它应该从系统中存在的任何网络接口上的指定端口接收 UDP 广播数据包。

但是,如果系统有多个相同子网地址的网络接口,则数据包只被第一个接口接受。

例如,如果 eth0 有 192.168.225.107,而 eth1 有 192.168.225.108,则仅接受来自 eth0 的数据包。

NIC 连接到不同的物理网络。根据 tcpdump,数据包存在于两个网络中。

代码(跳过错误检查):

sock = socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &on, sizeof(on));
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *) &s, sizeof(s));
bzero(&serv_addr_ip, sizeof(serv_addr_ip));
serv_addr_ip.sin_family = AF_INET;
serv_addr_ip.sin_port = htons(port);
serv_addr_ip.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr = (struct sockaddr *) &serv_addr_ip;
addr_len = sizeof(struct sockaddr_in);
bind(sock, serv_addr, addr_len);

while (1) {
    if ((chars = recvfrom(sock, var.buf, MSG_MAX, 0, serv_addr, &addr_len)) < 0) {
        ...
    }
...
}

【问题讨论】:

  • 如果 eth0 和 eth1 在同一个子网中,那是不是意味着每个广播数据包都会收到两次?这可能是它被过滤掉并仅交付给一个适配器的原因吗?
  • 这里有一个小技巧。网卡地址属于同一个子网,但物理上连接到不同的网络,有不同的数据包。
  • 您是否尝试将 eth0 配置为不同的子网?当 eth0 关闭时,您是否尝试过 eth1 是否正常工作?
  • 您不能绑定到多个网卡。您可以绑定到 INADDR_ANY,就像您正在做的那样。那么你的问题是什么?
  • 是的,然后我关闭了 eth0,来自 eth1 的数据包就可以了。我的问题是:为什么,虽然我使用的是 INADDR_ANY,但我只能看到来自分配给第一个网卡的地址的数据包。

标签: c linux sockets udp broadcast


【解决方案1】:

如果我的理解正确,您有两个 NIC,连接到两个物理网络(即网线、集线器),每个网络都有一个来自同一子网地址范围的单独 IP 地址?

简短的回答是您的网络配置错误。如果它们真的是独立的物理网络,那么它们应该有不同的子网地址。这取决于您对单独的物理网络,单独的硬件的意思?您不能有两个具有相同子网地址的单独子网。这就是我说你的网络配置错误的原因。

但是,我得到的印象是您正在尝试桥接两个网络,以便两个 NIC 属于同一个子网(不是分开的)。好吧,那么你应该桥接它们。您将两个 NIC 桥接在一起,并为桥分配一个 IP 地址。然后您将能够在两个 NIC 上接收数据包。

在 Linux 中:

brctl addbr br0
ifconfig eth0 0.0.0.0 down
ifconfig eth1 0.0.0.0 down
brctl addif br0 eth0
brctl addif br0 eth1
ifconfig eth0 up
ifconfig eth1 up
ifconfig br0 up
ifconfig br0 192.168.225.107 (or 192.168.225.108, whatever you prefer)

【讨论】:

  • 谢谢,这是个好主意。可以在测试机上运行,​​可惜我无法更改目标平台上的网络配置。
猜你喜欢
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多