получать многоадресную рассылку с определенного сетевого интерфейса в Linux

Я пытаюсь получить многоадресные данные от определенного сетевого интерфейса в CentOS 5.5.

sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(1234);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sd, (sockaddr*)&addr, sizeof(sockaddr_in));
setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);

Но я получаю пакеты со всех интерфейсов.

Что не так?


person Dima    schedule 24.09.2010    source источник
comment
Разве это не должно быть setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 4);? (обратите внимание на 4 против 5).   -  person Thomas M. DuBuisson    schedule 25.09.2010
comment
Я попробовал setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, eth0, 4), но setsockopt() не работает. Я думаю (не уверен), что 5 включает нулевое завершение.   -  person Dima    schedule 25.09.2010


Ответы (1)


Во-первых, проверьте, не сработал ли какой-либо из ваших вызовов, в данном случае socket,bind,setsockopt. Печать сообщения об ошибке с помощью функции perror() поможет вам диагностировать проблемы.

Однако для получения многоадресных дейтаграмм вам может потребоваться указать IP-адрес интерфейса, когда вы присоединяетесь к группе многоадресной рассылки, используя параметр сокета IP_ADD_MEMBERSHIP. Что-то вроде

  setsockopt (sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

где структура mreq

struct ip_mreq
{
        struct in_addr imr_multiaddr;   /* IP multicast address of group */
        struct in_addr imr_interface;   /* local IP address of interface */
};

Подробнее здесь.

person nos    schedule 24.09.2010
comment
Я изменил ADD_MEMBERSHIP согласно вам. Результат тот же: я все еще получаю многоадресные рассылки с других интерфейсов. Кстати, в моем реальном коде я проверяю возвращаемые значения всех API. Спасибо, Дима - person Dima; 25.09.2010