Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Как программно узнать свой внешний ip-адрес?


Автор: iNfantry 25.9.2006, 01:51
Подскажите пожалуйста как можно узнать свой external ip при подключении к интернету без использования каких-либо встроенных/установленных команд/программ системы, тоесть "своими руками". Вариант чтобы обратиться на какуюто страницу в сети, которая выдаст ип или послать dns-запрос тоже не очень интересен.. Как это сделать непосредственно? Например в вин32 кажется есть апи-функция которая возвращает сетевую информацию, а есть ли в *nix подобные средства или системные вызовы?

Автор: GrayCardinal 25.9.2006, 09:24
iNfantry
На страницу не обязательно. Можно просто сделать исходящий connect () куда-нибудь (без разницы, хоть на msn.com), затем на сокет :
getsockname(2)
(вернет адрес интерфейса с которого производился коннект).

Добавлено @ 09:24 
Сетевую информацию - можжно тупо распарсить вывод команды
/sbin/ifconfig
он вообще из /proc/ берет инфу, откуда точно правда не знаю

Автор: iNfantry 25.9.2006, 11:21
GrayCardinal, а не подскажешь по подробнее про getsockname() что она возвращает - дворд с ип адресом отправителя?

Автор: GrayCardinal 25.9.2006, 11:30
Цитата

#include <sys/socket.h>

int getsockname(int socket, struct sockaddr *address,
                socklen_t *address_len);

Т.е. первый аргумент - дескриптор, второй - адрес (для IPv4 - на структура типа sockaddr_in (куда адрес уйдет)), второй - размер адреса (*address_len = 4)

Добавлено @ 11:31 
Если все нормально - возвращает ноль. Ну, это нормально :-)

Добавлено @ 11:32 
в sockaddr_in.s_addr
если память не изменяет - DWORD с адресом.

Автор: iNfantry 25.9.2006, 11:34
Всё, спасибо, в мануале нашел.

Опросить присвоенный локальный адрес (его иногда называют именем сокета) можно с помощью функции getsockname(): она помещает его в структуру sockaddr, на которую указывает аргумент address, а длину адреса записывает по указателю address_len. 

Код

#include <sys/socket.h>
int getsockname 
   (int sd, struct sockaddr *restrict address,
    socklen_t *restrict address_len);

Автор: GrayCardinal 25.9.2006, 11:35
Всегда пожалуйста :-)

Автор: iNfantry 25.9.2006, 11:35
Хех, почти одновременно smile)

Автор: dmiceman 1.10.2006, 09:13
я дико извиняюсь, но тут есть одна мааленькая тонкость.

адрес это штука привязанная не к компьютеру, а к интерфейсу. а интерфейс -- это сетевуха или модем или ppp или vpn или фиг знает что еще. из этого следует что адресов у компьютера может быть много. что бы не быть голословным скажу что на моем кпомпе их сейчас пять штук.

вот поэтому алгоритм тут должен быть такой -- читать таблицу интерфейсов и извлекать их адреса. делается это посредством getifaddrs() man-а на которую кстати нет, так что смотреть /usr/include/ifaddrs.h

отдельная тема -- это роутинг, поскольку только один интерфейс является дефолтным, адрес которого и можно, с натяжкой, назвать адресом компьютера. вот тут проще действительно /proc/net/route читать, потому как все равно более другой путь -- это ioctl()-ы.

Автор: sOckets 1.10.2006, 14:40
Ты получишь только локальные данные , а если тебе нужен твой действительно внешний IP , например конечный шлюз провайдера , то ты должен (имхо) узнавать в интернете , повесить где нибуть скрипт PHP который выдаёт твой IP (http://myip.ru) и просто каждый раз когда надо коннектиться и брать оттуда IP , а сокеты вам не помогут узнать какой IP у шлюза прова %)
Если конечно тебе это надо smile

Автор: GrayCardinal 2.10.2006, 05:20
dmiceman
ИМХО. человеку надо было узнать адрес с которого он будет производить подключение. Он его узнал. Зачем ему адреса интерфейсов, которые могут быть даже не подключены ?

Автор: dmiceman 3.10.2006, 01:49
Цитата(GrayCardinal @ 2.10.2006,  05:20)
dmiceman
ИМХО. человеку надо было узнать адрес с которого он будет производить подключение. Он его узнал. Зачем ему адреса интерфейсов, которые могут быть даже не подключены ?

мой ip сейчас 80.81.208.66, но это совсем не мой ip :-) нет у меня такого интерфейса ибо сижу за маскарадом. то есть тут вопрос -- нужен ли ip дефолтного интерфейса или нужен ip видный снаружи. если второе -- то да, надо смотреть чем-то внешним. если ip дефолтного интерфейса -- действовать по моему плану -- найти дефолтный роутинг, выдрать его интерфейс и найти адрес этого интерфейса.

Автор: GrayCardinal 3.10.2006, 07:21
Цитата

вопрос -- нужен ли ip дефолтного интерфейса или нужен ip видный снаружи

Угу. А еще уточнить - ГДЕ видный  smile 

ЗЫ
галку уже поставили, однако, тему ЗАКРЫЛИ  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)