package service import ( "context" "io" "net/http" "strings" "time" ) // IPFetcher 用于获取本机的公网 IPv4 和 IPv6 type IPFetcher struct { client *http.Client } func NewIPFetcher() *IPFetcher { return &IPFetcher{ client: &http.Client{Timeout: 5 * time.Second}, } } // GetIPv4 获取公网 IPv4 func (f *IPFetcher) GetIPv4(ctx context.Context) (string, error) { return f.fetchIP(ctx, "https://api.ipify.org") } // GetIPv6 获取公网 IPv6 func (f *IPFetcher) GetIPv6(ctx context.Context) (string, error) { return f.fetchIP(ctx, "https://api6.ipify.org") } func (f *IPFetcher) fetchIP(ctx context.Context, apiURL string) (string, error) { req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil) if err != nil { return "", err } resp, err := f.client.Do(req) if err != nil { return "", err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", http.ErrServerClosed // 简易错误 } ipBytes, err := io.ReadAll(resp.Body) if err != nil { return "", err } return strings.TrimSpace(string(ipBytes)), nil }