Получение собственного внешнего IP-адреса в POSIX C - PullRequest
3 голосов
/ 25 мая 2009

Я ищу свой собственный IP-адрес для публикации этой информации в одноранговой сети. В POSIX / C у нас есть getaddrinfo(NULL, ...), но, кажется, это всегда возвращает INADDR_ANY или INADDR_LOOPBACK, что мне бесполезно.

Есть предложения?

Ответы [ 6 ]

4 голосов
/ 26 мая 2009

Одна из проблем заключается в том, что, даже если вы получаете локальный IP-адрес, IP-адрес, видимый в остальной части Интернета, может отличаться из-за большого количества NAT , который, к сожалению, очень распространен , Использование IPv6, вероятно, устранит эту проблему, но сейчас это может быть не вариант для вас.

Чтобы получить общедоступный IP-адрес, вам потребуется протокол, созданный для этой цели, такой как STUN ( RFC 5389 ). В C .

есть общедоступные серверы STUN и уже существуют клиенты STUN.

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

RFC 5128, «Состояние одноранговой (P2P) связи через трансляторы сетевых адресов (NAT) ) ".
1 голос
/ 13 июня 2009

Я не пытаюсь усложнить ситуацию, хотя должен отметить, что один компьютер может иметь несколько IP-адресов. как правило, каждая сетевая карта будет иметь один.

более конкретный способ задать вопрос: «Как мне найти IP-адрес, который будет использоваться в качестве исходного адреса при подключении к foo.com.org?» Мне нравится ответ бортцмейера за это:)

1 голос
/ 25 мая 2009

По общему адресу, который вы говорите, по адресу, с которым коллеги вашего приложения могут связаться с вами. Единственный полностью защищенный способ - подключиться к известному «внешнему» одноранговому узлу и заставить его отправить вам адрес обратно.

0 голосов
/ 25 мая 2009

Если вы знаете имя вашего хоста, вы можете использовать gethostbyname, чтобы получить IP-адрес.

0 голосов
/ 25 мая 2009

Вы проверяли ai_next поле возвращаемой структуры?

getaddrinfo() возвращает связанный список адресов.

0 голосов
/ 25 мая 2009

Создайте сокет UDP, bind () для INADDR_ANY, подключите () к какому-либо адресу в Интернете, затем используйте getsockname () на сокете, чтобы узнать, какому адресу он был присвоен.

Другое хорошее решение, если сетевой протокол его поддерживает, - просто спросить своих партнеров по начальной загрузке, что они думают о вашем IP. Это позаботится о NAT автоматически.

...