package nets import ( "errors" "fmt" "math" "math/big" "net" "strconv" "strings" ) // GetHostIpv4 获取本地内网IP func GetHostIpv4() (string, error) { privates, err := getAllIPV4(func(ip net.IP) bool { return ip.IsPrivate() }) if err != nil { return "", err } if len(privates) == 0 { return "", errors.New("no private ip") } return privates[0], nil } func getAllIPV4(filter func(net.IP) bool) (ips []string, err error) { // 获取所有网卡 addrs, err := net.InterfaceAddrs() if err != nil { return } for _, addr := range addrs { // 这个网络地址是IP地址: ipv4, ipv6 ipNet, isIpNet := addr.(*net.IPNet) if isIpNet && !ipNet.IP.IsLoopback() { // 跳过IPV6 if ipNet.IP.To4() != nil { if filter(ipNet.IP) { ips = append(ips, ipNet.IP.String()) } } } } return } func Address2i64(addr string) (int64, error) { idx := strings.Index(addr, ":") if idx < 0 { return 0, fmt.Errorf("invalid addr %s", addr) } ip, port := addr[0:idx], addr[idx+1:] portI, err := strconv.Atoi(port) if err != nil { return 0, err } ipI, err := Ip2i64(ip) if err != nil { return 0, err } return (int64(portI) << 32) | ipI, nil } func I642Address(addr int64) string { port := addr >> 32 ip := addr & math.MaxUint32 return fmt.Sprintf("%s:%d", I642Ip(ip), port) } func Ip2i64(ip string) (int64, error) { ip4 := net.ParseIP(ip).To4() if ip4 == nil { return 0, fmt.Errorf("invalid ip %s", ip) } ret := big.NewInt(0) ret.SetBytes(ip4) return ret.Int64(), nil } func I642Ip(ip int64) string { return fmt.Sprintf("%d.%d.%d.%d", byte(ip>>24), byte(ip>>16), byte(ip>>8), byte(ip)) }