gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/gox/netx/network.go (about) 1 package netx 2 3 import ( 4 "fmt" 5 "github.com/pkg/errors" 6 "io" 7 "net" 8 "net/http" 9 "strings" 10 ) 11 12 const ( 13 networkSpliter = "@" 14 ) 15 16 func ParseNetwork(str string) (network, addr string, err error) { 17 if idx := strings.Index(str, networkSpliter); idx == -1 { 18 err = fmt.Errorf("addr: \"%s\" error, must be network@tcp:port or network@unixsocket", str) 19 return 20 } else { 21 network = str[:idx] 22 addr = str[idx+1:] 23 return 24 } 25 } 26 27 func ConvertAddr(addr string) (r string, err error) { 28 iip, geterr := GetIntranetIp() 29 if geterr != nil { 30 err = errors.Wrap(geterr, "get intranet ip") 31 return 32 } 33 ip := iip.String() 34 addr = strings.ReplaceAll(addr, "localnet", ip) 35 36 return addr, nil 37 } 38 39 func GetInternalIPByUDP() (string, error) { 40 // 思路来自于Python版本的内网IP获取,其他版本不准确 41 conn, err := net.Dial("udp", "8.8.8.8:80") 42 if err != nil { 43 return "", errors.New("internal IP fetch failed, detail:" + err.Error()) 44 } 45 defer conn.Close() 46 47 // udp 面向无连接,所以这些东西只在你本地捣鼓 48 res := conn.LocalAddr().String() 49 res = strings.Split(res, ":")[0] 50 return res, nil 51 } 52 53 func GetIntranetIp() (ip net.IP, err error) { 54 ifaces, err := net.Interfaces() 55 if err != nil { 56 return nil, err 57 } 58 59 addresses := []net.IP{} 60 for _, iface := range ifaces { 61 62 if iface.Flags&net.FlagUp == 0 { 63 continue // interface down 64 } 65 66 if iface.Flags&net.FlagLoopback != 0 { 67 continue // loopback interface 68 } 69 70 addrs, adderr := iface.Addrs() 71 if adderr != nil { 72 continue 73 } 74 75 for _, addr := range addrs { 76 var lip net.IP 77 switch v := addr.(type) { 78 case *net.IPNet: 79 lip = v.IP 80 case *net.IPAddr: 81 lip = v.IP 82 } 83 84 if lip == nil || lip.IsLoopback() { 85 continue 86 } 87 lip = lip.To4() 88 if lip == nil { 89 continue // not an ipv4 address 90 } 91 addresses = append(addresses, lip) 92 } 93 } 94 if len(addresses) == 0 { 95 return nil, fmt.Errorf("no address Found, net.InterfaceAddrs: %v", addresses) 96 } 97 //only need first 98 return addresses[0], nil 99 } 100 func GetExternalIP() (string, error) { 101 // 有很多类似网站提供这种服务,这是我知道且正在用的 102 // 备用:https://myexternalip.com/raw (cip.cc 应该是够快了,我连手机热点的时候不太稳,其他自己查) 103 response, err := http.Get("http://ip.cip.cc") 104 if err != nil { 105 return "", errors.New("external IP fetch failed, detail:" + err.Error()) 106 } 107 108 defer response.Body.Close() 109 res := "" 110 111 // 类似的API应当返回一个纯净的IP地址 112 for { 113 tmp := make([]byte, 32) 114 n, err := response.Body.Read(tmp) 115 if err != nil { 116 if err != io.EOF { 117 return "", errors.New("external IP fetch failed, detail:" + err.Error()) 118 } 119 res += string(tmp[:n]) 120 break 121 } 122 res += string(tmp[:n]) 123 } 124 125 return strings.TrimSpace(res), nil 126 } 127 128 func ConvertToZeroIP(addr string) string { 129 if addr == "" { 130 return addr 131 } 132 arr := strings.Split(addr, ":") 133 port := arr[1] 134 return "0.0.0.0:" + port 135 } 136 137 // 0.0.0.0:port 138 func ConvertZeroIPToPublic(addr string) string { 139 return strings.ReplaceAll(addr, "0.0.0.0", GetPulicIP()) 140 } 141 142 func GetPulicIP() string { 143 conn, _ := net.Dial("udp", "8.8.8.8:80") 144 defer conn.Close() 145 localAddr := conn.LocalAddr().String() 146 idx := strings.LastIndex(localAddr, ":") 147 return localAddr[0:idx] 148 } 149 150 func GetPublicAddr(addr string) (x string) { 151 arr := strings.Split(addr, ":") 152 if len(arr) == 0 { 153 return 154 } 155 if arr[0] == "" { 156 x = GetPulicIP() + addr 157 } else { 158 x = addr 159 } 160 return 161 }