在Golang的网络编程场景中,获取本机IP地址是一个高频需求,比如服务启动时打印本机监听地址、上报节点网络信息等。Golang的标准库net包提供了net.Interfaces方法,可以获取本机所有的网络接口信息,基于这些信息就能提取出对应的IP地址。

net.Interfaces方法的基本使用
net.Interfaces函数会返回本机所有的网络接口对象,每个接口对象包含了接口的名称、硬件地址、接口状态以及绑定的IP地址列表等信息。我们首先可以通过这个方法获取所有接口,再遍历每个接口的地址信息。
下面是一个最基础的获取所有网络接口信息的示例代码:
package main
import (
"fmt"
"net"
)
func main() {
// 获取所有网络接口
interfaces, err := net.Interfaces()
if err != nil {
fmt.Println("获取网络接口失败:", err)
return
}
// 遍历所有接口
for _, i := range interfaces {
fmt.Printf("接口名称: %s, 接口状态: %vn", i.Name, i.Flags)
// 获取当前接口的所有地址
addrs, err := i.Addrs()
if err != nil {
fmt.Println("获取接口地址失败:", err)
continue
}
// 遍历地址
for _, addr := range addrs {
fmt.Printf(" 地址: %sn", addr.String())
}
}
}
提取有效的本机IP地址
上面的代码会输出所有接口的地址,但其中包含很多不需要的内容,比如回环地址127.0.0.1、IPv6地址、以及接口处于关闭状态时的无效地址。我们需要对这些信息进行过滤,得到可用的本机IP地址。
过滤规则说明
- 排除回环接口:接口的Flags包含net.FlagLoopback的接口是回环接口,对应的IP通常是127.0.0.1,不属于本机对外IP
- 排除未启用的接口:接口的Flags不包含net.FlagUp的接口处于关闭状态,没有有效IP
- 排除IPv6地址:如果只需要IPv4地址,可以过滤掉IP地址中是IPv6类型的条目
- 排除链路本地地址:比如169.254开头的IPv4地址属于链路本地地址,通常也不是我们需要的对外IP
封装获取IPv4地址的函数
我们可以把过滤逻辑封装成一个函数,方便后续直接调用:
package main
import (
"fmt"
"net"
"strings"
)
// 获取本机所有有效的IPv4地址
func GetLocalIPv4Addrs() ([]string, error) {
var ipAddrs []string
// 获取所有网络接口
interfaces, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, i := range interfaces {
// 排除回环接口和未启用的接口
if i.Flags&net.FlagLoopback != 0 || i.Flags&net.FlagUp == 0 {
continue
}
// 获取接口的地址列表
addrs, err := i.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
// 将地址转换为IPNet类型,方便判断类型
ipNet, ok := addr.(*net.IPNet)
if !ok {
continue
}
// 排除IPv6地址
if ipNet.IP.To4() == nil {
continue
}
// 排除链路本地地址
if strings.HasPrefix(ipNet.IP.String(), "169.254") {
continue
}
ipAddrs = append(ipAddrs, ipNet.IP.String())
}
}
return ipAddrs, nil
}
func main() {
ips, err := GetLocalIPv4Addrs()
if err != nil {
fmt.Println("获取本机IP失败:", err)
return
}
if len(ips) == 0 {
fmt.Println("未找到有效的本机IPv4地址")
return
}
fmt.Println("本机有效IPv4地址:")
for _, ip := range ips {
fmt.Println(ip)
}
}
不同场景下的注意事项
在实际使用中,还需要注意几个常见的问题:
多网卡场景的处理
如果本机有多个物理网卡或者虚拟网卡,上面的方法会返回所有符合条件的IP地址。如果只需要获取某个特定网段的IP,可以在返回结果后进一步做网段匹配过滤。
系统差异问题
不同操作系统下net.Interfaces返回的结果会有差异,比如Linux系统下会包含docker、veth等虚拟网卡的接口,Windows系统下会有更多系统保留的虚拟接口,过滤逻辑需要根据实际场景调整。
权限问题
在部分系统中,获取网络接口信息不需要特殊权限,但如果程序运行在受限环境,可能会出现获取接口失败的情况,需要做好错误处理。
总结
使用Golang获取本机IP地址的核心是通过net.Interfaces获取网络接口,再遍历接口的地址信息做过滤。只要明确自己的过滤规则,就能得到符合需求的IP地址列表。上面的封装函数已经覆盖了大部分常见的过滤场景,开发者可以直接复用,也可以根据自己的需求调整过滤条件。
Golangnet_Interfaces本机IP地址网络信息获取修改时间:2026-07-20 22:21:26