python 获取本机 IP

总是会有获取本机 IP 的需求,但是就是这样一个简单的需求处理起来还是有很多需要细化、明确的东东。

1 什么是本机 IP?本机的外网 IP?本机的内网 IP?

2 是在 linux 上还是其他系统也要支持?

为此,咱今儿特意查了下谷歌娘,总结得到以下代码 支持linux 32/64, solaris, win.但是这里只是获取了一个 IP 而已,其他的需要可以在这个基础上对代码进行改造。

哦,对了,具体到要获取外网 ip 的话,可以随便向谷歌娘等发起一个 http 请求然后获取 ip。这也是一个挺有趣的做法,代码如下

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("gmail.com",80))
print(s.getsockname()[0])
s.close()

这里是正式的代码

def _get_host_ip(self):
    """Get a host IP. Just return only one IP if there are many IPs.

    Args:
        None
    Returns:
        a ip address string

    Raises:
        RuntimeError
    """
    import socket
    import struct
    import array
    import os

    ip = 'unknown'
    SIOCGIFCONF = 0x8912
    size = 40 if sys.maxint > 2 ** 32 else 32
    max_possible = 8
    ip = socket.gethostbyname(socket.gethostname())
    outbytes = 0
    try:
        if ip.startswith("127.") and os.name != "nt":
            import fcntl
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            while True:
                bytes = max_possible * size
                ifnames = array.array('B', '\0' * bytes)
                outbytes = struct.unpack('iL', fcntl.ioctl(
                    sock.fileno(),
                    SIOCGIFCONF,
                    struct.pack('iL', bytes, ifnames.buffer_info()[0])
                    ))[0]
                if outbytes == bytes:
                    max_possible *= 2
                else:
                    break
            nic_info = ifnames.tostring()
            for idx in range(0, outbytes, size):
                ip = socket.inet_ntoa(nic_info[idx + 20:idx + 24])
                if ip.startswith("127."):
                    ip = 'unknown'
                    continue
                else:
                    break
    except socket.herror, e:
        Log.info("can not get host ip: %s" % e)
        raise RuntimeError("failed to execute %s" % e)
    except socket.error, e:
        Log.info("can not get host ip: %s" % e)
        raise RuntimeError("failed to execute %s" % e)

    return ip

 

posted @ 2013-11-29 18:13  saru  阅读(458)  评论(0编辑  收藏  举报