У меня есть две сети связи в сети Интернет, и у меня есть два маршрута по умолчанию Установка:Невозможно прослушивать несколько сокетов при использовании BINDTODEVICE?
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
.
Запуск проводов на любом из интерфейсов показывает, что данные поступают успешно - то есть я могу видеть, что данные отправляются из Интернета на IP-адрес eth0 или eth1 в Wireshark (так что NAT тоже не проблема), но моя программа просто блоков на recvfrom
без получения каких-либо данных.
Я попытался использовать bind
на сокетах, чтобы заставить их прослушивать IP-адрес соответствующего интерфейса, а также попытался не использовать привязку, чтобы они прослушивали 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;
}
Пожалуйста, покажите свой код. Скорее всего, вы не настроите привязки. –
Привязки работают для отправки данных и для одного интерфейса работают для приема данных. Поэтому я сейчас не подозреваю эту часть. – erjiang
Не смешивайте 'bind()' и 'SO_BINDTODEVICE'. Используйте один или другой. Как правило, вы должны использовать 'bind()'. –