用go获取IPv4地址,WLAN的IPv4地址,本机公网IP地址详解

获取IPv4地址

下面的代码会打印出本机所有的IPv4地址。这个方法可能会返回多个IP地址,因为一台机器可能有多个网络接口,每个接口可能有一个或多个IP地址。

go 复制代码
package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for _, addr := range addrs {
		if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				fmt.Println("IPv4: ", ipnet.IP.String())
			}
		}
	}
}

运行结果:

makefile 复制代码
IPv4:  169.254.157.225
IPv4:  169.254.28.142
IPv4:  169.254.211.187
IPv4:  192.168.144.1
IPv4:  192.168.253.1
IPv4:  10.252.64.116
IPv4:  169.254.106.194
IPv4:  169.254.109.149
IPv4:  172.28.240.1

甚至比我在终端使用ipconfig命令得到的IPv4地址还要多。

获取WLAN的IPv4地址

当然这么多IPv4地址并不一定都是我们想要的,对于用wifi上网的电脑,我们想获取无线局域网适配器 WLAN的IPv4地址可以按下面的代码操作:

go 复制代码
package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	interfaces, err := net.Interfaces()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for _, i := range interfaces {
		if i.Name == "WLAN" {
			addrs, err := i.Addrs()
			if err != nil {
				fmt.Println(err)
				continue
			}

			for _, addr := range addrs {
				if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
					if ipnet.IP.To4() != nil {
						fmt.Println("IPv4: ", ipnet.IP.String())
					}
				}
			}
		}
	}
}

运行结果:

makefile 复制代码
IPv4:  10.252.64.116

经过和上图比对,结果正确。

获取本机公网IP地址

那如果我们想获取本机的公网IP地址,那该怎么操作呢?我这里介绍两种方法:

第一种方法将通过与Google的公共DNS服务器建立UDP连接来获取公网IP地址。

go 复制代码
package main

import (
	"fmt"
	"net"
)

func main() {
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn.Close()

	localAddr := conn.LocalAddr().(*net.UDPAddr)

	fmt.Println("My public IP address is:", localAddr.IP.String())
}

运行结果:

csharp 复制代码
My public IP address is: 10.252.64.116

经过比对,结果正确。我们可以发现如果我们的电脑是用WiFi上网的,用此方法得出的结果与WLAN的IPv4地址相同。

第二种方法依赖于第三方服务,如果该服务不可用,可能无法获取到IP地址。此外,由于这个方法涉及到网络通信,所以可能会比获取本地IP地址慢一些。同时该方法出错的风险也较高。

go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	resp, err := http.Get("https://api.ipify.org")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	ip, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("My public IP address is: ", string(ip))
}

除了使用 https://api.ipify.org,还有其他一些服务可以提供公网IP地址,例如 https://ifconfig.mehttps://icanhazip.com

相关推荐
游戏开发爱好者830 分钟前
HTTPS 内容抓取实战 能抓到什么、怎么抓、不可解密时如何定位(面向开发与 iOS 真机排查)
android·网络协议·ios·小程序·https·uni-app·iphone
舒一笑2 小时前
PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致!
后端·程序员·intellij idea
简单点了4 小时前
go前后端项目的启动 、打包和部署
开发语言·后端·golang
雨夜之寂4 小时前
mcp java实战 第一章-第一节-MCP协议简介.md
java·后端
Fms_Sa4 小时前
UDP的一次双向通信
网络·网络协议·udp
摇滚侠4 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 核心语法 笔记39
spring boot·笔记·后端·thymeleaf
Code blocks6 小时前
GB28181视频服务wvp搭建(二)
后端·音视频
keer_zu6 小时前
一个Modbus-TCP传感器数据传输方案
网络·网络协议·tcp/ip
码事漫谈6 小时前
C++与C#布尔类型深度解析:从语言设计到跨平台互操作
后端
程序新视界6 小时前
在MySQL中,一条SQL语句的执行全流程是怎样的?
数据库·后端·mysql