见过很多获取服务器本地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
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
声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客
本文链接地址: Python 优雅获取本机 IP 方法 – https://www.chenyudong.com/archives/python-get-local-ip-graceful.html
2017 年 4 月 26 日 — 14:06
有意思,谢谢分享! 请问这个站点提供 RSS 订阅么?
2017 年 4 月 29 日 — 13:43
现在还有订阅的用户了?感觉自动Google的reader下架后,这类需求就很少了。 地址:https://www.chenyudong.com/feed
2017 年 11 月 3 日 — 17:05
Excellent!厉害!
2018 年 2 月 26 日 — 16:12
确实厉害,解决了我的问题,感谢。 我一直寻思的方法是,先获取所有ip,根据ip描述信息,比如本地连接、无线网络连接、eth0之类判断真实ip。 再次感谢!
2018 年 2 月 28 日 — 11:14
ip route get 1 | awk ‘{print $NF;exit}’
2018 年 3 月 2 日 — 14:44
很精简,写shell脚本的时候不错
2018 年 3 月 20 日 — 10:41
我在Windows上获取了是192.168.x.x的IP啊,能获取外网IP吗
2018 年 3 月 21 日 — 08:06
这个192.168.*就是你的内网ip吧。因为很多场景下公网ip无法直接获取,所以都需要远程访问网站获取到公网ip。
2018 年 7 月 15 日 — 16:28
python怎么能得到能够定位本机地理位置的信息 内网ip好像不行 公网ip和本机应该也不是在一个地理位置吧 比如用谷歌地图的时候 谷歌是怎么知道你的位置的呢
2018 年 7 月 22 日 — 15:12
应该是有集采数据的地方。比如在家里用手机去连接wifi,对外暴露了一个公网IP,操作系统也许记录现在的手机地理位置。然后PC访问的时候,刚好公网IP一致,那么就对应上了。