2013-01-23 2 views
12

Как связать сокет с определенным сетевым интерфейсом? Я попытался использовать setsockopt на стороне сервера, но клиенты все равно могут получить доступ к сервису через оба интерфейса eth0 и lo.связать сокет с сетевым интерфейсом

Я могу достичь этого, установив конкретный IP-адрес, используя serv_addr.sin_addr.s_addr.

Но я подозреваю, что мы можем привязываться к интерфейсу, используя только setsockopt (без упоминания IP-адреса).

ответ

2

Единственный способ вы можете сделать это, как вы уже -

, установив конкретный IP-адрес с помощью serv_addr.sin_addr.s_addr

Вы не можете сделать это, не зная адреса связываться.

Вы можете использовать ioctl s, чтобы определить текущий IP-адрес, если вам нужно, хотя в наши дни может быть более умный способ - в последнее время я не много сделал в современных дистрибутивах Linux.

+0

Thnks joe. могу ли я узнать использование setsockopt с SO_BINDTODEVICE? – user2003595

14

Вы можете привязать к определенному интерфейсу, установив опцию сокета SO_BINDTODEVICE.

struct ifreq ifr; 

memset(&ifr, 0, sizeof(ifr)); 
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0"); 
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) { 
    ... error handling ... 
} 

Предупреждение: Вы должны быть корень и иметь возможность CAP_NET_RAW для того, чтобы использовать эту опцию.

Второй способ заключается в том, что вы можете разрешить IP-адрес, привязанный к интерфейсу, с помощью getifaddrs().

Следуйте последней ссылке для исчерпывающего примера.

+0

Я знал, что должен быть лучший путь, чем ioctl! :-) – Joe

+0

Вы правы .... обновлено;) –

+0

У меня новый вопрос, так ли имеет значение eth0 и eth1 имеют одинаковый IP-адрес, используя ваш метод? – Splash

Смежные вопросы