
本文介绍如何使用 go 语言读取 json 配置文件,动态解析 tcp/udp 端口列表,并逐个执行网络连通性检测,适用于服务健康检查、网络诊断等场景。
本文介绍如何使用 go 语言读取 json 配置文件,动态解析 tcp/udp 端口列表,并逐个执行网络连通性检测,适用于服务健康检查、网络诊断等场景。
在实际运维与开发中,经常需要对目标主机的多个端口进行连通性验证(例如检查 Web 服务是否监听 80/443、DNS 是否响应 53 端口等)。硬编码端口不仅难以维护,也无法快速适配不同环境。Go 提供了简洁而强大的标准库支持——通过 encoding/json 解析配置、net.Dial 执行连接、os 操作文件,即可构建一个轻量、可复用的端口探测工具。
以下是一个完整、健壮的实现示例。我们首先定义配置结构体,支持 port(整数)和 protocol(字符串,如 "tcp" 或 "udp"),然后从 ports.json 文件中加载配置,遍历并发起连接测试:
package main
import (
"encoding/json"
"fmt"
"net"
"os"
"time"
)
// portDef 表示单个端口检测项,字段名需与 JSON key 严格对应
type portDef struct {
Port int `json:"port"`
Protocol string `json:"protocol"`
}
func main() {
host := "golang.org" // 可替换为命令行参数或环境变量,增强灵活性
// 1. 打开并读取配置文件
file, err := os.Open("ports.json")
if err != nil {
fmt.Fprintf(os.Stderr, "❌ 无法打开配置文件 ports.json: %v\n", err)
os.Exit(1)
}
defer file.Close()
// 2. 解析 JSON 到切片
var ports []portDef
if err := json.NewDecoder(file).Decode(&ports); err != nil {
fmt.Fprintf(os.Stderr, "❌ JSON 解析失败: %v\n", err)
os.Exit(1)
}
// 3. 遍历端口列表,逐一检测连通性
fmt.Printf("? 开始检测 %s 的 %d 个端口...\n", host, len(ports))
for i, p := range ports {
addr := fmt.Sprintf("%s:%d", host, p.Port)
fmt.Printf("[%d/%d] 正在连接 %s://%s ...\n", i+1, len(ports), p.Protocol, addr)
// 设置超时避免长期阻塞(推荐:TCP 建议 3–5 秒,UDP 注意无连接特性)
conn, err := net.DialTimeout(p.Protocol, addr, 5*time.Second)
if err != nil {
fmt.Printf(" ⚠️ %s://%s — 失败: %v\n", p.Protocol, addr, err)
continue
}
conn.Close()
fmt.Printf(" ✅ %s://%s — 成功\n", p.Protocol, addr)
}
fmt.Println("✅ 所有端口检测完成。")
}? 配置文件示例(ports.json):
[
{"port": 80, "protocol": "tcp"},
{"port": 443, "protocol": "tcp"},
{"port": 53, "protocol": "udp"},
{"port": 22, "protocol": "tcp"}
]⚠️ 注意事项:
- UDP 连通性检测具有局限性:
net.Dial("udp", ...)仅验证本地 socket 创建成功及地址可达性,不保证远端服务真正响应(UDP 是无连接协议)。如需真实验证,需配合发送/接收自定义数据包(如 DNS 查询),建议搭配net.DialUDP和业务逻辑实现。 - 建议添加连接超时(如本例中的
DialTimeout),防止因防火墙拦截或路由黑洞导致程序长时间挂起。 - 生产环境中,可进一步扩展:支持主机名列表、并发检测(使用 goroutine +
sync.WaitGroup)、结果结构化输出(JSON/CSV)、日志记录、命令行参数(如-host,-config)等。
该方案结构清晰、依赖零外部库,是 Go 新手理解文件 I/O、JSON 解析与网络编程的理想入门实践。



















