见过很多获取服务器本地 IP 的代码, 个人觉得都不是很好, 例如以下这些
不推荐: 靠猜测去获取本地 IP 方法
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import socket
- import fcntl
- import struct
- def get_ip_address(ifname):
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- return socket.inet_ntoa(fcntl.ioctl(
- s.fileno(),
- 0x8915, # SIOCGIFADDR
- struct.pack('256s', ifname[:15])
- )[20:24])
- print "br1 ="+ get_ip_address('br1')
- print "lo =" + get_ip_address('lo')
- print "virbr0 =" + get_ip_address('virbr0')
这类代码带有猜测的行为.
如果机器上只有 eth0 或者 只有 bond0 上有 IP, 那么此类代码都有可能失败, 而且还不容易移植到其他平台上.
不推荐: 通过 hostname 来获取本机 IP
- '''
- 遇到问题没人解答? 小编创建了一个 Python 学习交流 QQ 群:***
- 寻找有志同道合的小伙伴, 互帮互助, 群里还有不错的视频学习教程和 PDF 电子书!
- '''
- import socket
- print(socket.gethostbyname(socket.gethostname()))
- # 有可能出现这个情况
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- socket.gaierror: [Errno -2] Name or service not known
这个方法是通过获取 hostname, 然后再通过 hostname 反查处机器的 IP. 这个方法也是不推荐的. 因为很多的机器没有规范这个 hostname 的设置.
另外就是有些服务器会在 /etc/hosts 中添加本机的 hostname 的地址, 这个做法也不是不可以, 但是如果设置成了 127.0.0.1, 那么获取出来的 IP 就都是这个地址了.
通过 UDP 获取本机 IP, 目前见过最优雅的方法
这个方法是目前见过最优雅获取本机服务器的 IP 方法了. 没有任何的依赖, 也没有去猜测机器上的网络设备信息.
而且是利用 UDP 协议来实现的, 生成一个 UDP 包, 把自己的 IP 放如到 UDP 协议头中, 然后从 UDP 包中获取本机的 IP.
这个方法并不会真实的向外部发包, 所以用抓包工具是看不到的. 但是会申请一个 UDP 的端口, 所以如果经常调用也会比较耗时的, 这里如果需要可以将查询到的 IP 给缓存起来, 性能可以获得很大提升.
- # 在 shell 中可以一行调用, 获取到本机 IP
- python -c "import socket;print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])"
- 10.12.189.16
- # 可以封装成函数, 方便 Python 的程序调用
- import socket
- def get_host_ip():
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s.connect(('8.8.8.8', 80))
- ip = s.getsockname()[0]
- finally:
- s.close()
- return ip
来源: http://www.bubuko.com/infodetail-3279769.html