
获取局域网 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 Client、NewFuture/DDNS 都是这么做的,一般 DDNS 客户端则不支持使用局域网 IP 。如果使用上述代码或思路,就可以方便获取局域网 IP 、简化程序设计、简化用户配置。
1 proxytoworld 2021 年 10 月 19 日 这是适用于 网卡和外头连接的,如果有几个网卡,那些网卡不和外界连接的话就没办法了,这个获取本机 IP 的实现在 mirai 木马里面有 |
2 starsky007 OP @proxytoworld 我看原帖里有提到“Works even if all interfaces are unplugged from the network”,即使没有外网连接,也能获取默认路由 IP 。 |
3 adoal 2021 年 10 月 19 日 “不够便携”……机翻的? |
4 starsky007 OP @adoal 只有代码是搬运的,其他是我自己写的。protable/便携,意思是,不同环境下只需要配置一次;表达可能有点生硬,您有什么建议? |
5 princelai 2021 年 10 月 19 日 via Android @starsky007 结合上下文,不能在别的机器上用,应该翻译成不便移植更好吧 |
6 simple2025 2021 年 10 月 19 日 |
8 dingwen07 2021 年 10 月 20 日 via iPhone socket.gethostbyname(socket.gethostname()) |
9 dingwen07 2021 年 10 月 20 日 via iPhone #8 盲猜的,没试过 |
10 kokutou 2021 年 10 月 20 日 via Android 局域网 IP 默认路由 IP |
11 raysonx 2021 年 10 月 20 日 via iPad IPv4 only 的。。。。 |
12 skinny 2021 年 10 月 20 日 10.255.255.255 换成任意 IP 结果也是一样的 |
13 starsky007 OP @princelai “可移植”一般指的是二进制文件在不同操作系统平台上能运行。 |
14 starsky007 OP @chenqh 好问题。准确地说,代码不是获取局域网 IP,而是获取具有默认路由的本地 IP 。 |
15 starsky007 OP @dingwen07 原帖里其他回答也说了你说的这种写法,是不一样的。 |
16 starsky007 OP |
17 starsky007 OP @skinny 原帖里说了为什么要用 10.255.255.255 ,有差别。 |
18 starsky007 OP 还是要看一下原帖,帖子只是搬运代码、加了一点点自己的评论,并没有把原帖里面的讨论全部翻译过来。 |
19 ungrown 2021 年 10 月 20 日 @dangyuluo #7 咱也没必要转进到“信达雅”吧,再说“便携”其实挺信达雅的。 把 portable 这个词用来指代“轻便性”、“自适应性”、“可移植性”或者“自带运行环境无需额外安装”,本来就是类似于比喻的修辞用法,大家觉得这个词表达效果很精妙所以变成了常用语。 portable 的精髓就是讲究一个“随遇而安”,借用“便携”的表意来表达这份“随意性”、“轻便性”,倒并非刻意指代“移植”,所以直接按照字面意思来翻译就挺好。 |
20 ungrown 2021 年 10 月 20 日 我觉得这个函数的局限性还是应该体现在这个帖子的标题当中的,那就是用它写回答的人所表达的那样:它只能获取到设备的“主”IP 地址(也就是附带默认路由的那个地址),而并不能列出所有网络接口上的地址。 |
21 Wincer 2021 年 10 月 20 日 试试 psutil 这个库 |
22 starsky007 OP |
23 julyclyde 2021 年 10 月 20 日 我们这里都是用 magic number 8915 的,嘿嘿 然后到 mac 上就不行了 |
24 exiaohao 2021 年 10 月 20 日 这个面对大多数情况应该是够了吧,而且是挺巧妙的 但是如果对 10.255.255.255 这个地址 有什么策略路由或者走的网卡不一样可能会有不一样的结果?赶脚还能用来探测不同地址的不同路由 hh |
25 skinny 2021 年 10 月 20 日 @starsky007 原帖说的是广播地址就可以,因为程序不能直接使用广播地址。并不是说一定要 10.255.255.255 |
26 ZeroDu 2021 年 10 月 21 日 这个不错,在 java 里面怎么实现? |
27 vanton 2021 年 11 月 9 日 本地目录装个 psutil ,然后直接用 psutil.net_if_addrs() 不就得了。 |