在当今云计算和分布式系统的世界中,网络起着至关重要的作用。网络中最常见的任务之一是获取计算机的本地出站 IP 地址。这对于多种原因都很有用,例如在网络上识别您的计算机、检查网络连接或访问需要您的 IP 地址的外部服务。
在这篇博文中,我们将探讨如何在 Go 应用程序中获取本地出站 IP 地址,并解释可用的不同方法。
本地IP地址与公共IP地址
在开始之前,让我们回顾一下本地 IP 地址和公共 IP 地址之间的区别。
本地 IP 和公共 IP 是计算机网络中使用的两种类型的 IP 地址。它们之间的主要区别在于它们的使用范围和可达性。
本地 IP 地址用于本地网络(例如家庭或办公室网络)内的通信。它也称为私有 IP 地址,由本地路由器分配给设备。本地 IP 地址通常以192.168.x.x、172.16.x.xto172.31.x.x或开头10.x.x.x。
另一方面,公共IP地址用于通过互联网进行通信。它由互联网服务提供商 (ISP) 分配给设备,并且在全球范围内是唯一的。对于需要在本地网络外部进行通信(例如访问网站或远程服务器)的设备来说,公共 IP 地址是必需的。
总之,本地 IP 地址用于网络内部通信,而公共 IP 地址用于通过 Internet 进行外部通信。
在这篇博文中,我们将向您展示如何提取计算机的本地 IP 地址。
使用 UDP 获取首选出站 IP 地址
从 Go 应用程序中获取本地 IP 地址的第一种方法是使用UDP(用户数据报协议)连接。您需要准备一个到任何外部地址的 UDP 连接,然后从这样的连接中您可以提取首选的本地出站 IP 地址。查看GetLocalIP()以下示例中的函数
package main
import (
"fmt"
"log"
"net"
)
func GetLocalIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddress := conn.LocalAddr().(*net.UDPAddr)
return localAddress.IP
}
func main() {
fmt.Println(GetLocalIP())
}
我们使用包net.Dial()中的函数net准备与 Google DNS 服务器的 UDP 连接 ( 8.8.8.8)。目的地址和端口并不重要,甚至可能不存在,唯一的要求是该地址是外部的。由于 UDP 的工作原理,无论如何都不会建立连接 - 不执行握手,也不发送数据。
在这个例子中,我们如果要获得是IPv6的地址,只需要把 8.8.8.8:80,换成 [2600::]80,就可以获得 IPv6地址了。
此示例的目的是获取 UDP 连接在向目标地址发送数据时将使用的本地 IP 地址。LocalAddr()这可以使用创建连接的方法来完成。它返回net.Addr接口,然后可以使用类型断言将其强制转换为特定的接口net.UDPAddr,以便可以将 IP 地址提取为net.IP结构体。
通过循环所有网络接口地址获取本地IP地址
获取本地 IP 地址的另一种方法是迭代所有网络接口地址。可以使用该函数检索它们net.InterfaceAddrs()。看一下例子:
package main
import (
"fmt"
"log"
"net"
)
func GetLocalIPs() ([]net.IP, error) {
var ips []net.IP
addresses, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, addr := range addresses {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
ips = append(ips, ipnet.IP)
}
}
}
return ips, nil
}
func main() {
ips, err := GetLocalIPs()
if err != nil {
log.Fatal(err)
}
fmt.Println(ips)
}
我们将所有地址转换为该net.IPNet结构,然后过滤掉环回地址并仅将IPv4 IP 添加到结果列表中。此方法提取所有本地地址,因此如果您的计算机分配了多个本地 IP,则生成的切片将包含多个元素。
参考文章
发表评论