go语言获取IP地址并返回

2025-06-26
36次阅读
没有评论

自从用上了ddns以后,就想自己弄一个接口来获取vps的IP。

前几天在腾讯的Edgeone边缘函数和Cloudflare边缘函数上试过了,效果非常棒!

但是吧,他们都有限制,所以自己弄一个比较好。

听说go语言负载极强,所以决定使用go,最主要的还是之前没接触过go语言,但这一次接触觉得挺好玩。

需要预先部署go环境:

debian安装go语言环境

下面开始:

宝塔后台随便建一个静态网站:

进入到文件路径下:

新建一个 main.go 文件,填入代码:

go语言获取IP地址并返回

也可以命令行操作:

cd /www/wwwroot/域名
sudo nano main.go

粘贴代码保存即可。

代码如下:

package main

import (
	"fmt"
	"net"
	"net/http"
	"strings"
)

func extractIP(addr string) string {
	// 处理IPv6带端口的情况(格式为[IPv6]:port)
	if strings.HasPrefix(addr, "[") {
		// 去除方括号
		end := strings.Index(addr, "]")
		if end > 0 {
			return addr[1:end]
		}
	}
	
	// 处理IPv4带端口的情况
	if idx := strings.LastIndex(addr, ":"); idx != -1 {
		// 检查是否是IPv6地址(包含多个冒号)
		if strings.Count(addr, ":") > 1 {
			return addr // 已经是完整IPv6地址
		}
		return addr[:idx] // IPv4地址去除端口
	}
	
	return addr
}

func getIPHandler(w http.ResponseWriter, r *http.Request) {
	var ip string
	
	// 优先级顺序获取IP
	if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
		ips := strings.Split(xff, ",")
		ip = strings.TrimSpace(ips[0])
	} else if xrip := r.Header.Get("X-Real-IP"); xrip != "" {
		ip = xrip
	} else if cfip := r.Header.Get("CF-Connecting-IP"); cfip != "" {
		ip = cfip
	} else {
		ip = r.RemoteAddr
	}
	
	// 特殊处理IPv6地址
	ip = extractIP(ip)
	
	fmt.Fprintf(w, "%s", ip)
}

func main() {
	http.HandleFunc("/", getIPHandler)
	fmt.Println("服务器启动成功,正在监听端口 8080...")
	
	listener, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Printf("服务器启动失败: %v\n", err)
		return
	}
	
	if err := http.Serve(listener, nil); err != nil {
		fmt.Printf("服务器运行错误: %v\n", err)
	}
}

代码填写完后,需要开始编译:

在ssh命令行下:

go build -o app main.go
chmod +x app

就两行代码编译后出现一个七八兆大小的app文件。

随后 ./app 执行即可。

长时间启动也可以像我一样使用宝塔,用“进程守护管理器”启动。

go语言获取IP地址并返回

编译后使用Supervisor进程守护的配置:

go语言获取IP地址并返回

访问你的:http://IP地址:8080 即可

需要开放端口,也可以使用nginx反向代理:

在nginx配置文件中填入即可:

location / {
      proxy_pass http://localhost:8080;
      proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $remote_addr;
    }

端口可以自己定义,8080被其他程序占用就自己改端口,改完记得重新编译。

和Java一样,不愧是编译语言,动个符号都得重新编译。改bug还得是解释性语言好用。

注:目前代码还是有问题的,在使用cdn的情况下,在机器上curl ip查询域名 返回的只有默认IP(可能是v4也可能是v6),不能添加-4-6来指定获取IPv4或者IPv6的IP。

正文结束
自由书生
版权声明:本站原创文章,由 自由书生 于2025-06-26发表,共计1816字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码