Я использую скрипт Python для отправки пакетов UDP на сервер, который зарегистрирует мой скрипт для получения уведомлений от сервера. Протокол требует, чтобы я отправил свой собственный IP-адрес и порт, на который я хочу получать эти уведомления, поэтому это должен быть адрес, доступный из сети сервера.
Решения должны работать по крайней мере на Windows XP и выше, предпочтительно на Mac OS X, так как это моя платформа разработки.
Первый шаг - получить IP-адрес любого из моих интерфейсов. В настоящее время я использую общепринятый подход для разрешения имени хоста машины:
def get_local_address():
return socket.gethostbyname(socket.gethostname())
Это работает только иногда. В настоящее время он возвращает 172.16.249.1
, который является адресом виртуального интерфейса, используемого VM Ware, так что это проблема.
Намного лучше было бы получить IP-адрес интерфейса по умолчанию, который в большинстве случаев должен быть правильным.
Еще лучше было бы получить фактический IP-адрес, используемый для соединения с сервером по протоколу, ориентированному на соединение, например TCP. Я действительно могу получить этот адрес, но не без попытки открыть соединение:
def get_address_to_connect_to(server_addr):
non_open_port = 50000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((server_addr, non_open_port))
except socket.error:
pass
else:
s.close() # just in case
return s.getsockname()[0]
Это будет блокировать до истечения некоторого времени ожидания TCP в случае, если сервер недоступен или злой межсетевой экран между ними блокирует пакеты ICMP. Есть ли лучший способ получить эту информацию?