搬运一段 Python 获取局域网 IP 的方法,十分优雅!

2021-10-19 20:27:28 +08:00
 starsky007

代码

获取局域网 IP,一般做法是先枚举网卡、再获取 IP,但是这种做法的缺点是,不够便携,在不同的机器上需要不同的配置,代码实现上也比较啰嗦。这里搬运一段来自 Stack Overflow 的代码,适用性强、十分优雅。使用 Python 实现,我也就发在 Python 节点了,其他语言也可以借鉴。

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

来源: networking - Finding local IP addresses using Python's stdlib - Stack Overflow

应用场景

比如,DDNS 客户端,如果想要为局域网 IP 绑定域名,往往需要人工选择网卡或者正则表达式匹配域名,我见过的几个 DDNS 客户端比如 No-IP Dynamic Update ClientNewFuture/DDNS 都是这么做的,一般 DDNS 客户端则不支持使用局域网 IP 。如果使用上述代码或思路,就可以方便获取局域网 IP 、简化程序设计、简化用户配置。

5477 次点击
所在节点    Python
27 条回复
proxytoworld
2021-10-19 21:41:21 +08:00
这是适用于 网卡和外头连接的,如果有几个网卡,那些网卡不和外界连接的话就没办法了,这个获取本机 IP 的实现在 mirai 木马里面有
starsky007
2021-10-19 21:49:09 +08:00
@proxytoworld
我看原帖里有提到“Works even if all interfaces are unplugged from the network”,即使没有外网连接,也能获取默认路由 IP 。
adoal
2021-10-19 22:04:44 +08:00
“不够便携”……机翻的?
starsky007
2021-10-19 22:16:44 +08:00
@adoal
只有代码是搬运的,其他是我自己写的。protable/便携,意思是,不同环境下只需要配置一次;表达可能有点生硬,您有什么建议?
princelai
2021-10-19 22:33:03 +08:00
@starsky007 结合上下文,不能在别的机器上用,应该翻译成不便移植更好吧
chenqh
2021-10-19 23:58:43 +08:00
这个东西好像不对,如果用了 vpn 的话

PS D:\ccode\HelloWorld> & C:/Users/Lenovo/AppData/Local/Microsoft/WindowsApps/python3.8.exe d:/ccode/HelloWorld/local.py
10.110.110.122
PS D:\ccode\HelloWorld> & C:/Users/Lenovo/AppData/Local/Microsoft/WindowsApps/python3.8.exe d:/ccode/HelloWorld/local.py
192.168.50.235
dangyuluo
2021-10-20 00:08:32 +08:00
@princelai 现在社会步伐这么快,谁有空来翻译地信雅达
dingwen07
2021-10-20 00:25:58 +08:00
socket.gethostbyname(socket.gethostname())
dingwen07
2021-10-20 00:26:31 +08:00
#8 盲猜的,没试过
kokutou
2021-10-20 04:39:56 +08:00
局域网 IP❎
默认路由 IP✅
raysonx
2021-10-20 04:47:17 +08:00
IPv4 only 的。。。。
skinny
2021-10-20 08:03:27 +08:00
10.255.255.255 换成任意 IP 结果也是一样的
starsky007
2021-10-20 09:31:43 +08:00
@princelai
“可移植”一般指的是二进制文件在不同操作系统平台上能运行。
starsky007
2021-10-20 09:52:28 +08:00
@chenqh
好问题。准确地说,代码不是获取局域网 IP,而是获取具有默认路由的本地 IP 。
starsky007
2021-10-20 09:53:49 +08:00
@dingwen07
原帖里其他回答也说了你说的这种写法,是不一样的。
starsky007
2021-10-20 09:54:26 +08:00
@kokutou
👍
starsky007
2021-10-20 10:03:15 +08:00
@skinny
原帖里说了为什么要用 10.255.255.255 ,有差别。
starsky007
2021-10-20 10:08:12 +08:00
还是要看一下原帖,帖子只是搬运代码、加了一点点自己的评论,并没有把原帖里面的讨论全部翻译过来。
ungrown
2021-10-20 10:33:20 +08:00
@dangyuluo #7 咱也没必要转进到“信达雅”吧,再说“便携”其实挺信达雅的。
把 portable 这个词用来指代“轻便性”、“自适应性”、“可移植性”或者“自带运行环境无需额外安装”,本来就是类似于比喻的修辞用法,大家觉得这个词表达效果很精妙所以变成了常用语。
portable 的精髓就是讲究一个“随遇而安”,借用“便携”的表意来表达这份“随意性”、“轻便性”,倒并非刻意指代“移植”,所以直接按照字面意思来翻译就挺好。
ungrown
2021-10-20 10:37:53 +08:00
我觉得这个函数的局限性还是应该体现在这个帖子的标题当中的,那就是用它写回答的人所表达的那样:它只能获取到设备的“主”IP 地址(也就是附带默认路由的那个地址),而并不能列出所有网络接口上的地址。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/809003

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX