Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Используйте netifaces
модуль. Поскольку сети сложны, использование netifaces может быть немного хитрым, но здесь - как сделать то, что Вы хотите:
>>> import netifaces
>>> netifaces.interfaces()
['lo', 'eth0']
>>> netifaces.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:11:2f:32:63:45'}], 2: [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::211:2fff:fe32:6345%eth0'}]}
>>> for interface in netifaces.interfaces():
... print netifaces.ifaddresses(interface)[netifaces.AF_INET]
...
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
[{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}]
>>> for interface in netifaces.interfaces():
... for link in netifaces.ifaddresses(interface)[netifaces.AF_INET]:
... print link['addr']
...
127.0.0.1
10.0.0.2
Это может быть сделано немного более читаемым как это:
from netifaces import interfaces, ifaddresses, AF_INET
def ip4_addresses():
ip_list = []
for interface in interfaces():
for link in ifaddresses(interface)[AF_INET]:
ip_list.append(link['addr'])
return ip_list
, Если Вы хотите адреса IPv6, используйте AF_INET6
вместо AF_INET
. Если Вы задаетесь вопросом, почему netifaces
списки использования и словари повсеместно, это - потому что одиночный компьютер может иметь несколько NICs, и каждый NIC может иметь несколько адресов, и каждый адрес имеет свой собственный набор опций.
Это - Linux только, но существует очень простой рецепт здесь http://code.activestate.com/recipes/439094/
, Это, вероятно, использует подобный код для netifaces пакет упомянутый в другом ответе (но текущая версия, связанная здесь)
, socket.getaddrinfo () на самом деле не возвращает связанный IP-адрес для устройства. Если Ваш файл hosts содержит строку с "127.0.1.1 yourhost.example.com yourhost", который является общей конфигурацией, getaddrinfo только собирается возвратиться 127.0.1.1.
Необходимо непосредственно получить настроенные IP-адреса всего IP, например, путем выполнения ifconfig и парсинга его вывода (также возможно сделать то, что ifconfig делает непосредственно в Python , , видят, как это сделано в C). Если Вы хотите имена хоста, используйте gethostbyaddr.
Вот процедура для поиска всех интерфейсов IPv4 и IPv6. Как указывалось на предыдущем плакате, socket.gethostbyname_ex () не работает для IPv6, а документация Python рекомендует вместо этого использовать socket.getaddressinfo () .
Эта процедура добавляет интерфейс обратного вызова IPv4 (127.0 .0.1), и если есть какие-либо интерфейсы IPv6, он также добавляет интерфейс обратного вызова IPv6 (:: 1). На моей машине socket.getaddrinfo () предоставит мне один или оба из них, но только если у меня нет других доступных интерфейсов.
Для моих нужд я хотел попытаться открыть сокет UDP на указанном порту на каждом из мои доступные интерфейсы, поэтому в коде есть «порт» и socket.SOCK_DGRAM. Их можно безопасно изменить, например, если у вас нет порта в памяти.
addrinfo_ipv4 = socket.getaddrinfo(hostname,port,socket.AF_INET,socket.SOCK_DGRAM)
addrinfo_ipv6 = []
try:
addrinfo_ipv6 = socket.getaddrinfo(hostname,port,socket.AF_INET6,socket.SOCK_DGRAM)
except socket.gaierror:
pass
addrinfo = [(f,t,a) for f,t,p,cn,a in addrinfo_ipv4+addrinfo_ipv6]
addrinfo_local = [(socket.AF_INET,socket.SOCK_DGRAM,('127.0.0.1',port))]
if addrinfo_ipv6:
addrinfo_local.append( (socket.AF_INET6,socket.SOCK_DGRAM,('::1',port)) )
[addrinfo.append(ai) for ai in addrinfo_local if ai not in addrinfo]