【发布时间】: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()。 -
两者都试过了——上面写着...