欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

断网之后,,为什么这个 代码还能获取到 ip 地址 通义千问 chatgpt 有大用 有大大用 有大大大用

#!/usr/bin/python3
#

import socket

def get_local_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('8.8.8.8', 80))  #这是DNS服务器的 UDP 80端口
    local_ip = s.getsockname()[0]
    s.close()
    return local_ip
print(get_local_ip())


断网之后,,为什么这个 代码还能获取到 ip 地址

你提出的问题非常好:“断网之后,为什么这段代码还能获取到 IP 地址?”

我们来一步步分析原因。


📌 你的代码逻辑

python
编辑
def get_local_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('8.8.8.8', 80))  # 注意:8.8.8.8 是 Google 的 DNS 服务器,但这里用的是 UDP 连接(SOCK_DGRAM)
    local_ip = s.getsockname()[0]
    s.close()
    return local_ip

关键点:

  • 创建一个 UDP 套接字SOCK_DGRAM)。

  • 调用 connect() 到一个远程地址(8.8.8.8:80)。

  • 然后调用 getsockname() 获取本地绑定的 IP 地址。

⚠️ 注意:UDP 是无连接协议,connect() 在 UDP 中 不会真正发送任何网络包它只是在本地设置“默认目标地址”,方便后续 send()/recv() 使用。所以这个 connect() 不会触发实际的网络通信!


✅ 为什么断网也能获取 IP?

因为:

  1. connect() 对 UDP 套接字是“伪连接”
    它只是告诉操作系统:“如果我之后用 send() 发数据,默认发给这个地址”。不会发送任何数据包,也不会检查网络是否连通。

  2. getsockname() 返回的是本地绑定的地址
    当你 connect() 到一个远程地址时,操作系统会根据本地路由表决定“如果要发包到 8.8.8.8,应该从哪个本地网卡出去”,然后自动将套接字绑定到该网卡的 IP 上(通常是你的局域网 IP,如 192.168.x.x10.x.x.x)。

  3. 这个过程完全在本地完成,不需要网络连通性
    即使你拔了网线、关了 Wi-Fi、甚至没有互联网,只要你的网卡有配置 IP 地址(比如通过 DHCP 或静态配置),操作系统就能根据路由表算出“出口 IP”。


🔍 举个例子

假设你电脑的 Wi-Fi 网卡 IP 是 192.168.1.100,即使你断开了互联网(比如路由器没连外网),但你的电脑仍然有这个 IP。

当你执行:

python
编辑
s.connect(('8.8.8.8', 80))

系统查路由表发现:“去 8.8.8.8 要走默认网关,出口是 Wi-Fi 网卡”,于是就把套接字绑定到 192.168.1.100

所以 getsockname() 返回的就是 192.168.1.100 —— 这只是一个本地 IP,不代表你能上网!


❓那怎么判断是否真的联网?

如果你想知道是否真正能访问互联网,不能只看有没有本地 IP,而应该

  • 尝试 实际发送/接收数据(比如用 socket.sendto() + recvfrom() 查询 DNS)

  • 或者用更高层的方法,比如 requests.get("http://www.google.com")(带超时)

例如: # OK 有大用

python
编辑
import socket

def is_connected():
    try:
        sock = socket.create_connection(("8.8.8.8", 53), timeout=3)
        sock.close()
        return True
    except OSError:
        return False

这里用 TCP 连接 到 8.8.8.8:53(DNS 端口),会真正尝试建立连接,能反映网络连通性。


✅ 总结

问题回答
断网后为什么还能获取 IP?因为 connect() 在 UDP 中不发包,getsockname() 只返回本地路由决定的出口 IP,完全依赖本地配置,无需网络连通。
这个 IP 能说明能上网吗?不能! 它只是本地网卡的 IP,可能根本无法访问外网。
如何真正检测联网?需要实际尝试连接或发送数据(如 TCP 连接、HTTP 请求等)。

希望这能彻底解答你的疑惑!如果还有其他网络编程相关问题,欢迎继续问




普通分类: