上一篇
如何用Go快速获取服务器IP地址?
- 行业动态
- 2025-05-10
- 5
在Go语言中,可通过net包获取服务器IP地址,常见方法是遍历网络接口(net.Interfaces),筛选有效IPv4/IPv6地址,排除回环地址及无效接口,可通过解析主机名或直接读取接口信息实现,注意处理多网卡及内外网IP区分场景。
在开发Web应用或搭建服务器时,获取客户端或服务器的IP地址是常见的需求,以下将详细介绍Go语言中获取服务器IP的多种方法,包括本地IP、公网IP以及处理代理场景的方案,并提供可直接运行的代码示例。
获取本地服务器IP
通过Go标准库获取本机所有网络接口的IP地址:
package main import ( "fmt" "net" ) func getLocalIPs() []string { var ips []string interfaces, _ := net.Interfaces() for _, iface := range interfaces { addrs, _ := iface.Addrs() for _, addr := range addrs { switch v := addr.(type) { case *net.IPNet: if !v.IP.IsLoopback() && v.IP.To4() != nil { ips = append(ips, v.IP.String()) } } } } return ips } func main() { fmt.Println("本地网络接口IP:", getLocalIPs()) }
这段代码会过滤掉IPv6地址和回环地址,仅输出IPv4地址。
获取服务器公网IP
通过访问外部API获取公网IP(需联网):
package main import ( "fmt" "io/ioutil" "net/http" ) func getPublicIP() (string, error) { resp, err := http.Get("https://api.ipify.org?format=text") if err != nil { return "", err } defer resp.Body.Close() ip, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(ip), nil } func main() { ip, _ := getPublicIP() fmt.Println("服务器公网IP:", ip) }
Web服务中获取客户端IP
在HTTP服务中正确处理代理转发的场景:
package main import ( "fmt" "net/http" "strings" ) func getClientIP(r *http.Request) string { // 处理代理情况 xForwardedFor := r.Header.Get("X-Forwarded-For") if xForwardedFor != "" { ips := strings.Split(xForwardedFor, ",") return strings.TrimSpace(ips[0]) } // 直接连接的IP ip, _, _ := net.SplitHostPort(r.RemoteAddr) return ip } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "客户端IP: %s", getClientIP(r)) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
特殊场景处理
IPv6地址处理:
func isIPv6(ip string) bool { return strings.Contains(ip, ":") }
容器化环境:
在Docker/Kubernetes中建议通过环境变量获取:func getPodIP() string { return os.Getenv("POD_IP") }
注意事项
安全建议:
- 避免直接暴露服务器IP
- 使用防火墙限制访问
- 对客户端IP进行有效性验证
性能优化:
- 本地IP可缓存结果
- 外部API调用需设置超时
client := http.Client{Timeout: 3 * time.Second}
完整代码示例
整合本地IP与公网IP获取:
package main import ( "fmt" "net" "net/http" "io/ioutil" ) func main() { // 获取本地IP addrs, _ := net.InterfaceAddrs() for _, addr := range addrs { if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { fmt.Println("本地IPv4:", ipnet.IP) } } } // 获取公网IP resp, err := http.Get("https://ifconfig.me/ip") if err == nil { defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println("公网IP:", string(body)) } }
扩展工具推荐
第三方库:
- github.com/gin-gonic/gin 的
ClientIP()
方法 - github.com/sebest/xff 处理X-Forwarded-For头
- github.com/gin-gonic/gin 的
调试工具:
curl ifconfig.me nc -zv <你的服务器IP> 端口
引用说明:
- 公网IP检测API使用ipify服务
- Go标准库
net
包文档参考官方文档 - HTTP头处理规范参考RFC 7239