如何在 Go 中获取本地 IP 地址?
Posted
技术标签:
【中文标题】如何在 Go 中获取本地 IP 地址?【英文标题】:How do I get the local IP address in Go? 【发布时间】:2014-06-26 19:52:55 【问题描述】:我想获取计算机的 IP 地址。我使用了下面的代码,但它返回127.0.0.1
。
我想获取 IP 地址,例如10.32.10.111
,而不是环回地址。
name, err := os.Hostname()
if err != nil
fmt.Printf("Oops: %v\n", err)
return
addrs, err := net.LookupHost(name)
if err != nil
fmt.Printf("Oops: %v\n", err)
return
for _, a := range addrs
fmt.Println(a)
【问题讨论】:
【参考方案1】:当机器上存在多个 ip 接口时,这里有一个更好的解决方案来检索首选的出站 ip 地址。
import (
"log"
"net"
"strings"
)
// Get preferred outbound ip of this machine
func GetOutboundIP() net.IP
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil
log.Fatal(err)
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP
【讨论】:
我一直在寻找相同的东西,这只是一个对我来说很好用的东西:),顺便说一下,我想知道你为什么要与 Google Dns 进行 udp 连接,以及“整个”的价值是什么conn.LocalAddr().String()" ? 实际上它没有建立任何连接,并且目的地根本不需要存在 :) 所以,代码实际上做的是获取本地地址(如果它会连接到该目标) ,您可以更改为您想要的任何其他 IP 地址。conn.LocalAddr().String()
是本地 ip 和端口。
这比公认的解决方案要好。即使您在默认路由网关的子网上有 2 个 IP 地址(比如有线和无线 IP),这(对我来说)正在选择流量将使用的默认 IP。
@darkwing 它使用 udp 协议,与 TCP 不同,它没有握手也没有连接。因此,目标不需要在那里,您将收到出站 IP。
@darkwing:将其视为“逻辑”连接,而不是“物理”连接。【参考方案2】:
你需要遍历所有网络接口
ifaces, err := net.Interfaces()
// handle err
for _, i := range ifaces
addrs, err := i.Addrs()
// handle err
for _, addr := range addrs
var ip net.IP
switch v := addr.(type)
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
// process IP address
Play(取自 util/helper.go)
【讨论】:
谢谢,已将其添加到答案中 util/helper.go 可能是这个 code.google.com/p/whispering-gophers/source/browse/util/… 。 IPv6 怎么样?这似乎只适用于 IPv4 地址。 对 net.Interfaces() 的调用在我的 Linux 主机(Manjaro,当前)上没有返回错误和 0 个接口play.golang.org/p/0K5bL_eqFm :(【参考方案3】:为确保您获得非环回地址,只需在迭代时检查 IP 不是环回即可。
// GetLocalIP returns the non loopback local IP of the host
func GetLocalIP() string
addrs, err := net.InterfaceAddrs()
if err != nil
return ""
for _, address := range addrs
// check the address type and if it is not a loopback the display it
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback()
if ipnet.IP.To4() != nil
return ipnet.IP.String()
return ""
【讨论】:
这是一个很好的解决方案,只要只有一个非环回接口可用。【参考方案4】:您的os.Hostname()
上的net.LookupHost()
可能总是会给您127.0.0.1,因为那是您的/etc/hosts
或等效项中的内容。
我想你要使用的是net.InterfaceAddrs()
:
func InterfaceAddrs() ([]Addr, error)
InterfaceAddrs 返回系统的网络接口地址列表。
【讨论】:
这有它自己的皱纹。地址以字符串形式提供。给定一个 IP 地址(特定的 Go 类型,而不是通用术语),没有直接的比较。要么需要将 IP 转换为字符串并进行比较,要么解析字符串以获取要比较的 IP,对于这个新手 Go 程序员来说,这两者都不是微不足道的。我正在寻找将字符串转换为 IP 的库程序,但还没有找到。 你指的Go类型的IP地址是什么? golang.org/pkg/net/#IP type IP []byte 我寻找的解析器就在页面下方: func ParseCIDR(s string) (IP, *IPNet, error) (似乎无法格式化这些行作为代码。)【参考方案5】:这对我有用:
host, _ := os.Hostname()
addrs, _ := net.LookupIP(host)
for _, addr := range addrs
if ipv4 := addr.To4(); ipv4 != nil
fmt.Println("IPv4: ", ipv4)
与发布者的示例不同,它仅返回非环回地址,例如10.120.X.X.
【讨论】:
但如果我使用 if 循环,它将是该循环内的本地...我想在此循环外使用 ipv4 值 @VijayKumar,var ipv4 net.IP
在循环之外使用ipv4 = addr.To4()
(而不是ipv4 := addr.To4()
【参考方案6】:
func GetInternalIP() string
itf, _ := net.InterfaceByName("enp1s0") //here your interface
item, _ := itf.Addrs()
var ip net.IP
for _, addr := range item
switch v := addr.(type)
case *net.IPNet:
if !v.IP.IsLoopback()
if v.IP.To4() != nil //Verify if IP is IPV4
ip = v.IP
if ip != nil
return ip.String()
else
return ""
【讨论】:
【参考方案7】:func resolveHostIp() (string)
netInterfaceAddresses, err := net.InterfaceAddrs()
if err != nil return ""
for _, netInterfaceAddress := range netInterfaceAddresses
networkIp, ok := netInterfaceAddress.(*net.IPNet)
if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil
ip := networkIp.IP.String()
fmt.Println("Resolved Host IP: " + ip)
return ip
return ""
【讨论】:
【参考方案8】:如果你只有一个 IP 地址,除了 127.0.0.1,你可以在这里查看代码。
conn,err := net.Dial("ip:icmp","google.com")
fmt.Println(conn.LocalAddr())
第二个参数可以是除127.0.0.1以外的任何IP地址
【讨论】:
您能否详细说明这与***.com/a/37382208/916440 有何不同?谢谢。以上是关于如何在 Go 中获取本地 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章