如何找到本地IP地址(即192.168.x。x或10.0.x.x)在Python平台独立,只使用标准库?


当前回答

一台计算机可以有多个网络接口(包括您提到的本地环回127.0.0.1)。就操作系统而言,它也是一个“真实IP地址”。

如果你想跟踪所有的接口,看看下面的Python包,参见:http://alastairs-place.net/netifaces/

我认为,如果您从主机文件中删除环回条目,就可以避免gethostbyname返回127.0.0.1。(有待核实)。

其他回答

对于linux,你可以使用hostname -I system命令的check_output,就像这样:

from subprocess import check_output
check_output(['hostname', '-I'])

在Linux上:

>>> import socket, struct, fcntl
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sockfd = sock.fileno()
>>> SIOCGIFADDR = 0x8915
>>>
>>> def get_ip(iface = 'eth0'):
...     ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
...     try:
...         res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
...     except:
...         return None
...     ip = struct.unpack('16sH2x4s8x', res)[2]
...     return socket.inet_ntoa(ip)
... 
>>> get_ip('eth0')
'10.80.40.234'
>>> 

好吧,这是Windows特定的,需要安装python WMI模块,但这似乎比不断尝试调用外部服务器要简单得多。这只是另一种选择,因为已经有很多好的选择,但它可能非常适合您的项目。

Import WMI

def getlocalip():
    local = wmi.WMI()
    for interface in local.Win32_NetworkAdapterConfiguration(IPEnabled=1):
        for ip_address in interface.IPAddress:
            if ip_address != '0.0.0.0':
                localip = ip_address
    return localip







>>>getlocalip()
u'xxx.xxx.xxx.xxx'
>>>

顺便说一下,WMI非常强大……如果你正在做任何窗口机器的远程管理,你一定要看看它能做什么。

这将在大多数linux盒子上工作:

import socket, subprocess, re
def get_ipv4_address():
    """
    Returns IP address(es) of current machine.
    :return:
    """
    p = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE)
    ifc_resp = p.communicate()
    patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
    resp = patt.findall(ifc_resp[0])
    print resp

get_ipv4_address()

供您参考,我可以验证该方法:

import socket
addr = socket.gethostbyname(socket.gethostname())

适用于OS X (10.6,10.5), Windows XP和管理良好的RHEL部门服务器。它不能在一个非常小的CentOS虚拟机上工作,我只是做了一些内核黑客。因此,对于该实例,您可以检查127.0.0.1地址,在这种情况下,执行以下操作:

if addr == "127.0.0.1":
     import commands
     output = commands.getoutput("/sbin/ifconfig")
     addr = parseaddress(output)

然后从输出中解析ip地址。应该注意的是,默认情况下ifconfig不在普通用户的PATH中,这就是为什么我在命令中给出完整的路径。我希望这能有所帮助。