流傳的go版本內網獲取都不准確,所以想到之前看到的python版本,通過擬一個UDP連接來獲取
package main
import (
"errors"
"fmt"
"io"
"net"
"net/http"
"strings"
)
func main() {
fmt.Println(GetExternalIP())
fmt.Println(GetInternalIP())
}
func GetInternalIP() (string, error) {
// 思路來自於Python版本的內網IP獲取,其他版本不准確
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
return "", errors.New("internal IP fetch failed, detail:" + err.Error())
}
defer conn.Close()
// udp 面向無連接,所以這些東西只在你本地搗鼓
res := conn.LocalAddr().String()
res = strings.Split(res, ":")[0]
return res, nil
}
func GetExternalIP() (string, error) {
// 有很多類似網站提供這種服務,這是我知道且正在用的
// 備用:https://myexternalip.com/raw (cip.cc 應該是夠快了,我連手機熱點的時候不太穩,其他自己查)
response, err := http.Get("http://ip.cip.cc")
if err != nil {
return "", errors.New("external IP fetch failed, detail:" + err.Error())
}
defer response.Body.Close()
res := ""
// 類似的API應當返回一個純凈的IP地址
for {
tmp := make([]byte, 32)
n, err := response.Body.Read(tmp)
if err != nil {
if err != io.EOF {
return "", errors.New("external IP fetch failed, detail:" + err.Error())
}
res += string(tmp[:n])
break
}
res += string(tmp[:n])
}
return strings.TrimSpace(res), nil
}