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