我正在使用python创建一个简单的服务器应用程序,我正在尝试将IP绑定到侦听套接字.我看过的一个例子使用了这个:
HOST = gethostbyaddr(gethostname())
在此之后稍微处理一下,它应该只给出主机IP作为字符串.这应该返回IPv4地址.但是当我运行此代码时,它会返回我的IPv6地址.为什么这样做以及如何获取我的IPv4地址?
如果相关,我使用的是windows vista和python 2.5
获取您的IP地址比您想象的更难.
检查我给出的答案,我找到了一个可靠的方法.
如果您不喜欢点击某些内容,这就是答案所说的:
使用该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
在整个地方使用列表和词典,那是因为一台计算机可以有多个NIC,每个NIC可以有多个地址,每个地址都有自己的一组选项.
IPv6优先于IPv4,因为它是较新的系列,如果您的主机名与多个系列相关联,通常就是您想要的.您应该使用getaddrinfo进行系列独立解析,这是一个例子,
import sys, socket; host = socket.gethostname(); result = socket.getaddrinfo(host, None); print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0]; result = socket.getaddrinfo(host, None, socket.AF_INET); print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0]; result = socket.getaddrinfo(host, None, socket.AF_INET6); print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
在双栈配置的主机上给出了以下内容,
family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0) family:2 socktype:1 proto:6 canonname: sockaddr:('10.6.28.31', 0) family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0)