代码拉取完成,页面将自动刷新
package iputil
import (
"net"
"net/http"
"strings"
Log "github.com/cihub/seelog"
)
// 获取访问IP
func GetIP(r *http.Request) string {
ip := r.Header.Get("X-Real-IP")
if net.ParseIP(ip) != nil {
return ip
}
ip = r.Header.Get("X-Forward-For")
for _, i := range strings.Split(ip, ",") {
if net.ParseIP(i) != nil {
return ip
}
}
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
Log.Error("获取访问IP地址发生异常:", err) //使用localhost会得到这个IP
return "0.0.0.0"
}
if net.ParseIP(ip) == nil {
return ip
}
if ip == "0:0:0:0:0:0:0:1" {
ip = "127.0.0.1"
} else if ip == "::1" {
ip = "127.0.0.1"
}
if ip != "127.0.0.1" {
return ip
}
result, err := GetOutBoundIP()
if err != nil {
return ip
}
return result
}
// 获取本机ip地址
func GetOutBoundIP() (ip string, err error) {
conn, err := net.Dial("udp", "8.8.8.8:53")
if err != nil {
Log.Error("获取本地IP地址发生异常:", err)
return
}
localAddr := conn.LocalAddr().(*net.UDPAddr)
ip = strings.Split(localAddr.String(), ":")[0]
return
}
// 获取请求中的IP
func RemoteIp(req *http.Request) string {
remoteAddr := req.Header.Get("X-Real-IP")
if net.ParseIP(remoteAddr) == nil {
remoteAddr = ""
}
if remoteAddr == "" {
remoteAddr = req.Header.Get("X-Forward-For")
for _, i := range strings.Split(remoteAddr, ",") {
if net.ParseIP(i) == nil {
remoteAddr = ""
}
}
}
if remoteAddr == "" {
temp, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
remoteAddr = ""
}
remoteAddr = temp
}
if net.ParseIP(remoteAddr) == nil {
remoteAddr = ""
}
if remoteAddr == "::1" || remoteAddr == "" {
remoteAddr = "127.0.0.1"
}
if remoteAddr == "127.0.0.1" {
//remoteAddr = GetLocalIpV4()
remoteAddr = GetLocal()
}
return remoteAddr
}
// getLocalIpV4 获取 IPV4 IP,没有则返回空
// 有返回虚拟网卡的风险
func GetLocalIpV4() string {
netInterfaces, err := net.Interfaces()
if err != nil {
panic(err)
}
for i := 0; i < len(netInterfaces); i++ {
if (netInterfaces[i].Flags & net.FlagUp) == 0 {
continue
}
flags := netInterfaces[i].Flags.String()
if !strings.Contains(flags, "up") || !strings.Contains(flags, "broadcast") {
continue //对于服务器而言,只会有一个网卡处于 up 且 broadcast 状态
}
addrs, _ := netInterfaces[i].Addrs()
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsLinkLocalUnicast() {
Log.Error(ipnet.IP.IsLinkLocalUnicast())
if ipnet.IP.To4() == nil {
continue
}
return ipnet.IP.String()
}
}
}
return ""
}
// 获取当前本地使用的主IP地址
func GetLocal() string {
conn, err := net.Dial("udp", "8.8.8.8:8") //使用UDP协议,需要担心访问不到8.8.8.8:8
if err != nil {
panic(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}
// 判断指定端口是否空闲,空闲返回true
// 利用Go标准库中的net包和错误处理来判断端口是否可用
func IsPortAvailable(port string) bool {
listener, err := net.Listen("tcp", ""+port)
if err != nil {
if opErr, ok := err.(*net.OpError); ok && opErr.Err.Error() == "listen tcp :8080: bind: address already in use" {
return false // 端口被占用
}
// 其他错误处理...
return false
}
defer func(li net.Listener) {
err := li.Close()
if err != nil {
Log.Error("Error closing listener:", err)
}
}(listener) // 关闭监听器以防资源泄露
return true // 端口可用
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。