Sockets Can';使用BINDTODEVICE时,是否无法侦听多个套接字?
我有两个到Internet的网络链接,并设置了两个默认路由:Sockets Can';使用BINDTODEVICE时,是否无法侦听多个套接字?,sockets,unix,udp,recvfrom,Sockets,Unix,Udp,Recvfrom,我有两个到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
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数据)在两个套接字上侦听,但我只能从路由中首先列出的接口成功读取数据<例如,code>eth0可以工作,但是我从绑定到eth1
的套接字中什么也得不到
在任何一个接口上运行wireshark都会显示数据成功进入-也就是说,我可以在wireshark中看到数据从Internet发送到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;
}
int-createDeviceBoundUDPSocket(uint32\u t sip、uint16\u t sport、const char*bind\u dev){
printf(“bind\u dev=%s”,bind\u dev);
int s=插座(AF INET,SOCK DGRAM,0);
int结果;
我的ip地址中的结构sockaddr\u;
如果(s<0){
佩罗(“插座”);
返回s;
}
memset(&my_ip_addr,0,sizeof(my_ip_addr));
我的ip地址sin家庭=家庭;
我的ip地址sin地址s地址=htonl(sip);
my_ip_addr.sin_port=htons(运动版);
//把这一部分注释掉似乎没有什么不同
//监听0.0.0.0或接口的IP都有相同的问题
结果=绑定(s,(struct sockaddr*)(&my_ip_addr),sizeof(my_ip_addr));
如果(结果<0){
perror(“绑定错误”);
返回结果;
}
如果(绑定开发){
//绑定到特定设备。
if(设置套接字选项,SOL_套接字,SO_绑定到设备,
绑定开发,strlen(绑定开发)+1){
perror(“错误绑定到设备”);
返回-1;
}
}
返回s;
}
如指南所示,解决方案是关闭反向路径过滤。不确定三个接口中的哪一个需要关闭,但是
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
成功了。请显示您的实际代码。您可能没有正确设置绑定。绑定用于发送数据,而对于一个接口,绑定用于接收数据。因此,我目前不怀疑这一部分。不要将
bind()
和So\u BINDTODEVICE
混用。用一个或另一个。通常,您应该使用bind()
。用这两种方法都试过-上面写过。。。