Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets Can';使用BINDTODEVICE时,是否无法侦听多个套接字?_Sockets_Unix_Udp_Recvfrom - Fatal编程技术网

Sockets Can';使用BINDTODEVICE时,是否无法侦听多个套接字?

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

我有两个到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数据)在两个套接字上侦听,但我只能从路由中首先列出的接口成功读取数据<例如,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()
。用这两种方法都试过-上面写过。。。