Зависит, что Вы подразумеваете под собственным IP-адресом. Системы имеют IP-адреса на нескольких подсетях (иногда несколько на подсеть), часть из который IPv4, некоторый IPv6 с помощью устройств как адаптеры Ethernet, петлевые интерфейсы, туннели VPN, мосты, виртуальные интерфейсы...
Я Вы имеете в виду IP-адрес, которым другое данное устройство может достигнуть Вашего компьютера, необходимо узнать, какая подсеть то есть, и о какой версии IP мы говорим. Кроме того, примите во внимание, что из-за NAT, выполненного брандмауэром/маршрутизаторами, IP-адрес интерфейса не может совпасть с удаленным хостом, видит входящее соединение от Вашего компьютера, прибывающего из.
Когда существует необычная маршрутизация от источника, или на протокол/порт, направляющий его, может быть трудным узнать, какой интерфейс использовался бы, чтобы говорить с одним удаленным компьютером по данному протоколу и даже затем, нет никакой гарантии, что IP-адрес того интерфейса может быть прямо адресуемым удаленным компьютером, желающим установить новое соединение с Вашим компьютером.
Для IPv4 (вероятно, работает на IPv6 также), прием, который работает во многих нельдах включая Linux для обнаружения, IP-адрес интерфейса, используемого для достижения данного хоста, состоит в том, чтобы использовать подключение (2) на сокете UDP и использовать getsockname ():
Например, на моем домашнем компьютере:
perl -MSocket -le 'socket(S, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
connect(S, sockaddr_in(1, inet_aton("8.8.8.8")));
print inet_ntoa((sockaddr_in(getsockname(S)))[1]);'
Использовался бы для обнаружения IP-адреса интерфейса, через который я достигну 8.8.8.8 (сервер DNS Google). Это возвратило бы что-то как "192.168.1.123", который является адресом интерфейса для маршрута по умолчанию к Интернету. Однако Google не видел бы запрос DNS от моей машины как прибывающий из того IP-адреса, который является частным, поскольку существует NAT, выполненный моим домашним широкополосным маршрутизатором.
подключение () на сокете UDP не отправляет пакета (UDP без установления соединения), но готовит сокет путем запросов таблицы маршрутизации.
Хорошо, найденный решением. Было действительно просто, это создает новое действие. Это столь же просто как: