0.0.0.0 与 127.0.0.1 的区别
这是一个非常经典的网络基础问题。简单来说,这涉及到 IP 地址的绑定(Binding)范围 以及 操作系统的网络协议栈如何过滤请求。
1. 127.0.0.1:自言自语模式
127.0.0.1 是一个特殊的本地回环地址(Loopback Address)。
-
原理:当你监听这个地址时,内核会将该端口锁定在
lo(还记得你刚才ip addr看到的第一个网卡吗?)这个虚拟设备上。 -
结果:数据包如果来自外部(比如
eth0网卡),操作系统会发现:“嘿,这个包是发给eth0的,但我的程序只在lo上等着呢。” 于是系统会直接丢弃这个包。 -
用途:通常用于开发阶段,或者用于同一台机器内部的组件通信(比如 Nginx 转发给后端的 Go 程序),这样安全性最高。
2. 0.0.0.0:广而告之模式
0.0.0.0 在监听时代表“所有可用的网络接口”。
-
原理:当你监听
0.0.0.0:8080时,你是在告诉操作系统:“不管是发往lo的、eth0(公网 IP)的,还是以后可能添加的 VPN 网卡的,只要目标端口是8080,全部交给我这个程序处理。” -
结果:外部用户通过你的公网 IP
38.147.170.196访问时,数据包从eth0进来,系统发现你监听了所有接口,于是连接成功。
3. “:8080”:Go 的默认便捷写法
在 Go 的 http.ListenAndServe 中,如果你省略 IP 只写冒号和端口(如 ":8080"),Go 默认就会绑定到 0.0.0.0(以及 IPv6 的 [::])。
- 它是最省心的写法,能确保你的程序在任何网络环境下都能被外界触达。
为什么不能直接写死公网 IP?
你可能会问:那我在代码里直接写 http.ListenAndServe("38.147.170.196:8080", nil) 行不行?
-
技术上行:这会让程序只监听那块特定的物理网卡。
-
实践中不好:
-
灵活性差:如果你把程序换到另一台服务器,IP 变了,你的程序就启动失败了(报
assign requested address错误)。 -
本地无法访问:如果你写死了公网 IP,有时在服务器内部通过
localhost访问反而会失败。
-
总结建议
-
开发调试:用
127.0.0.1:8080(防止别人偷看你的半成品)。 -
正式发布:用
0.0.0.0:8080或简写":8080"。
特别提醒:
一旦你用了 0.0.0.0,你的程序就完全暴露在公网了。如果你还没写好“授权码验证”逻辑,任何人只要知道你的 IP 都能访问你的接口。
既然你在做订阅制程序,你打算如何保护你的接口不被未授权的人通过公网直接调用?