我有两个到 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;
}