Golang如何获取客户端的IP和主机名

Golang如何获取客户端的IP和主机名 当客户端发起请求访问 REST API 时,我需要他们在同一 URL 资源上传递主机名和 IP 的详细信息,并在日志中捕获这些信息。请提供示例代码帮助我。

func main() {
    fmt.Println("hello world")
}
3 回复

这个可能符合你的需求:https://github.com/tomasen/realip

更多关于Golang如何获取客户端的IP和主机名的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这篇帖子有助于获取HTTP请求的IP地址,如果我对问题的理解正确的话。https://golangcode.com/get-the-request-ip-addr/

在Go中获取客户端IP和主机名可以通过net/http包的Request对象实现。以下是示例代码:

package main

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

func getClientInfo(r *http.Request) (ip, hostname string) {
    // 获取客户端IP
    ip = r.RemoteAddr
    if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
        ip = strings.Split(forwarded, ",")[0]
    }
    
    // 从IP解析主机名
    if ip != "" {
        if host, _, err := net.SplitHostPort(ip); err == nil {
            ip = host
        }
        if names, err := net.LookupAddr(ip); err == nil && len(names) > 0 {
            hostname = names[0]
        }
    }
    return
}

func handler(w http.ResponseWriter, r *http.Request) {
    ip, hostname := getClientInfo(r)
    
    // 记录日志
    log.Printf("Client IP: %s, Hostname: %s", ip, hostname)
    
    // 返回响应
    fmt.Fprintf(w, "IP: %s\nHostname: %s", ip, hostname)
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

如果使用反向代理,可以添加更完整的IP获取逻辑:

func getClientIP(r *http.Request) string {
    headers := []string{
        "X-Forwarded-For",
        "X-Real-Ip",
        "CF-Connecting-IP", // Cloudflare
    }
    
    for _, header := range headers {
        if ip := r.Header.Get(header); ip != "" {
            return strings.Split(ip, ",")[0]
        }
    }
    
    // 直接连接时的IP
    if ip, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
        return ip
    }
    
    return r.RemoteAddr
}

对于需要同时处理IPv4和IPv6的情况:

func handler(w http.ResponseWriter, r *http.Request) {
    ip := getClientIP(r)
    
    // 解析主机名
    var hostname string
    if addr, err := net.ResolveIPAddr("ip", ip); err == nil {
        if names, err := net.LookupAddr(addr.String()); err == nil && len(names) > 0 {
            hostname = strings.TrimSuffix(names[0], ".")
        }
    }
    
    log.Printf("Request from %s (%s)", ip, hostname)
    fmt.Fprintf(w, "IP: %s\nHostname: %s", ip, hostname)
}

注意:主机名解析可能因网络配置和DNS设置而失败,实际使用时需要处理错误情况。

回到顶部