golang中使用 request请求时候,url是域名,如何获取真实请求的IP地址?

golang中使用 request请求时候,url是域名,如何获取真实请求的IP地址?

在Go语言中,当使用域名发起HTTP请求时,可以通过以下两种方法获取实际连接的IP地址:

方法1:使用Client Trace(推荐)

利用http.Client的Trace功能捕获连接建立时的IP地址:

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptrace"
)

func main() {
	url := "https://example.com"

	// 创建Trace对象收集连接信息
	var remoteAddr string
	trace := &httptrace.ClientTrace{
		GotConn: func(connInfo httptrace.GotConnInfo) {
			remoteAddr = connInfo.Conn.RemoteAddr().String()
		},
	}

	req, _ := http.NewRequest("GET", url, nil)
	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))

	// 发送请求
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal("Request error:", err)
	}
	defer resp.Body.Close()

	fmt.Println("实际连接的IP地址:", remoteAddr) // 输出: 192.0.2.1:443
}

方法2:自定义Transport

通过自定义http.Transport在连接时捕获IP:

package main

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

type transport struct {
	realTransport http.RoundTripper
	remoteAddr    string
}

func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
	resp, err := t.realTransport.RoundTrip(req)
	if err == nil {
		t.remoteAddr = resp.Request.Context().Value(http.LocalAddrContextKey).(net.Addr).String()
	}
	return resp, err
}

func main() {
	url := "https://example.com"

	// 创建自定义Transport
	customTransport := &transport{
		realTransport: http.DefaultTransport,
	}

	client := &http.Client{
		Transport: customTransport,
	}

	resp, err := client.Get(url)
	if err != nil {
		log.Fatal("Request error:", err)
	}
	defer resp.Body.Close()

	fmt.Println("实际连接的IP地址:", customTransport.remoteAddr) // 输出: 192.0.2.1:443
}

关键说明:

  1. DNS解析过程:Go自动处理域名到IP的解析,以上方法捕获的是解析后的实际IP
  2. 输出格式:获取的是IP:端口格式(如192.0.2.1:443
  3. 重定向处理
    • Trace方法自动处理重定向,每次连接都会更新IP
    • Transport方法需手动处理重定向(可禁用重定向client.CheckRedirect = func(...) error { return http.ErrUseLastResponse }
  4. 连接复用:如果使用连接池,相同域名的后续请求可能复用连接,不会触发新IP获取

应用场景:

  • 调试DNS解析问题
  • 记录请求的真实服务器IP
  • 验证CDN/代理配置
  • 地理位置服务(需配合IP数据库)

注意:如果域名对应多个IP,实际连接的IP由Go的DNS解析器决定(默认使用系统DNS),可能每次请求结果不同(负载均衡场景)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码讲故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值