–
相关函数介绍
func ParseIP(s string) IP ParseIP parses s as an IP address, returning the result. The string s can be in dotted decimal (“192.0.2.1”) or IPv6 (“2001:db8::68”) form. If s is not a valid textual representation of an IP address, ParseIP returns nil. func InterfaceAddrs() ([]Addr, error) InterfaceAddrs returns a list of the system’s unicast interface addresses. The returned list does not identify the associated interface; use Interfaces and Interface.Addrs for more detail. type IPNet An IPNet represents an IP network. type IPNet struct { IP IP // network number Mask IPMask // network mask } type IP []byte An IP is a single IP address, a slice of bytes. Functions in this package accept either 4-byte (IPv4) or 16-byte (IPv6) slices as input. Note that in this documentation, referring to an IP address as an IPv4 address or an IPv6 address is a semantic property of the address, not just the length of the byte slice: a 16-byte slice can still be an IPv4 address. func IPv4(a, b, c, d byte) IP IPv4 returns the IP address (in 16-byte form) of the IPv4 address a.b.c.d.
点到为止,更详细的请看文档:https://golang.org/pkg/net
外网IP和内网IP
tcp/ip协议中,专门保留了三个IP地址区域作为私有地址,其地址范围如下:
10.0.0.0/8:10.0.0.0~10.255.255.255 172.16.0.0/12:172.16.0.0~172.31.255.255 192.168.0.0/16:192.168.0.0~192.168.255.255
什么是内网IP
一些小型企业或者学校,通常都是申请一个固定的IP地址,然后通过IP共享(IP Sharing),使用整个公司或学校的机器都能够访问互联网。而这些企业或学校的机器使用的IP地址就是内网IP,内网IP是在规划IPv4协议时,考虑到IP地址资源可能不足,就专门为内部网设计私有IP地址(或称之为保留地址),一般常用内网IP地址都是这种形式的:10.X.X.X、172.16.X.X-172.31.X.X、192.168.X.X等。需要注意的是,内网的计算机可向Internet上的其他计算机发送连接请求,但Internet上其他的计算机无法向内网的计算机发送连接请求。我们平时可能在内网机器上搭建过网站或者FTP服务器,而在外网是不能访问该网站和FTP服务器的,原因就在于此。
什么是公网IP
公网IP就是除了保留IP地址以外的IP地址,可以与Internet上的其他计算机随意互相访问。我们通常所说的IP地址,其实就是指的公网IP。互联网上的每台计算机都有一个独立的IP地址,该IP地址唯一确定互联网上的一台计算机。这里的IP地址就是指的公网IP地址。
怎样理解互联网上的每台计算机都有一个唯一的IP地址
其实,互联网上的计算机是通过“公网IP+内网IP”来唯一确定的,就像很多大楼都是201房间一样,房间号可能一样,但是大楼肯定是唯一的。公网IP地址和内网IP地址也是同样,不同企业或学校的机器可能有相同的内网IP地址,但是他们的公网IP地址肯定不同。那么这些企业或学校的计算机是怎样IP地址共享的呢?这就需要使用NAT(Network Address Translation,网络地址转换)功能。当内部计算机要连接互联网时,首先需要通过NAT技术,将内部计算机数据包中有关IP地址的设置都设成NAT主机的公共IP地址,然后再传送到Internet,虽然内部计算机使用的是私有IP地址,但在连接Internet时,就可以通过NAT主机的NAT技术,将内网我IP地址修改为公网IP地址,如此一来,内网计算机就可以向Internet请求数据了。
获取公网ip
百度ip,即可查看公网ip curl命令查看公网ip curl ipinfo.io/ip 通过http://myexternalip.com/raw获取公网ip func get_external() string { resp, err := http.Get("http://myexternalip.com/raw") if err != nil { return "" } defer resp.Body.Close() content, _ := ioutil.ReadAll(resp.Body) //buf := new(bytes.Buffer) //buf.ReadFrom(resp.Body) //s := buf.String() return string(content) }
获取本地ip
package main import ( "fmt" "net" "os" ) func GetIntranetIp() { addrs, err := net.InterfaceAddrs() if err != nil { fmt.Println(err) os.Exit(1) } for _, address := range addrs { // 检查ip地址判断是否回环地址 if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { fmt.Println("ip:", ipnet.IP.String()) } } } } func main() { GetIntranetIp() }
通过dns服务器8.8.8.8:80获取使用的ip
func GetPulicIP() string { conn, _ := net.Dial("udp", "8.8.8.8:80") defer conn.Close() localAddr := conn.LocalAddr().String() idx := strings.LastIndex(localAddr, ":") return localAddr[0:idx] }
判断是否是公网ip
func IsPublicIP(IP net.IP) bool { if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() { return false } if ip4 := IP.To4(); ip4 != nil { switch true { case ip4[0] == 10: return false case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: return false case ip4[0] == 192 && ip4[1] == 168: return false default: return true } } return false }
ip地址string转int
func inet_aton(ipnr net.IP) int64 { bits := strings.Split(ipnr.String(), ".") b0, _ := strconv.Atoi(bits[0]) b1, _ := strconv.Atoi(bits[1]) b2, _ := strconv.Atoi(bits[2]) b3, _ := strconv.Atoi(bits[3]) var sum int64 sum += int64(b0) << 24 sum += int64(b1) << 16 sum += int64(b2) << 8 sum += int64(b3) return sum }
ip地址int转string
func inet_ntoa(ipnr int64) net.IP { var bytes [4]byte bytes[0] = byte(ipnr & 0xFF) bytes[1] = byte((ipnr >> 8) & 0xFF) bytes[2] = byte((ipnr >> 16) & 0xFF) bytes[3] = byte((ipnr >> 24) & 0xFF) return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0]) }
判断ip地址区间
func IpBetween(from net.IP, to net.IP, test net.IP) bool { if from == nil || to == nil || test == nil { fmt.Println("An ip input is nil") // or return an error!? return false } from16 := from.To16() to16 := to.To16() test16 := test.To16() if from16 == nil || to16 == nil || test16 == nil { fmt.Println("An ip did not convert to a 16 byte") // or return an error!? return false } if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 { return true } return false }
通过淘宝接口根据公网ip获取国家运营商等信息
接口:
http://ip.taobao.com/service/getIpInfo.php?ip=
type IPInfo struct { Code int `json:"code"` Data IP `json:"data` } type IP struct { Country string `json:"country"` CountryId string `json:"country_id"` Area string `json:"area"` AreaId string `json:"area_id"` Region string `json:"region"` RegionId string `json:"region_id"` City string `json:"city"` CityId string `json:"city_id"` Isp string `json:"isp"` } func TabaoAPI(ip string) *IPInfo { url := "http://ip.taobao.com/service/getIpInfo.php?ip=" url += ip resp, err := http.Get(url) if err != nil { return nil } defer resp.Body.Close() out, err := ioutil.ReadAll(resp.Body) if err != nil { return nil } var result IPInfo if err := json.Unmarshal(out, &result); err != nil { return nil } return &result }
完整代码
package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net" "net/http" "os" "strconv" "strings" ) type IPInfo struct { Code int `json:"code"` Data IP `json:"data"` } type IP struct { Country string `json:"country"` CountryId string `json:"country_id"` Area string `json:"area"` AreaId string `json:"area_id"` Region string `json:"region"` RegionId string `json:"region_id"` City string `json:"city"` CityId string `json:"city_id"` Isp string `json:"isp"` } func main() { ipaddr := GetExternal() ipaddr = strings.Replace(ipaddr,"\n","", -1) fmt.Println("pub ip: ", ipaddr) result := TaobaoAPI(ipaddr) if result != nil { fmt.Println("cn", result.Data.Country) fmt.Println("city", result.Data.Area) fmt.Println("city", result.Data.City) fmt.Println("isp", result.Data.Isp) } GetIntranetIp() a := IPAtoi(net.ParseIP(ipaddr)) fmt.Println("base 10: ", a) fmt.Println("ipv4: ", IPItoa(a)) fmt.Println("check: ", IpBetween(net.ParseIP("0.0.0.0"), net.ParseIP("255.255.255.255"), net.ParseIP(ipaddr))) fmt.Println("public: ", IsPublicIP(net.ParseIP("169.254.85.131"))) fmt.Println("public ip: ", GetPublicIP()) } func GetExternal() string { resp, err := http.Get("http://myexternalip.com/raw") if err != nil { return "" } defer resp.Body.Close() content, _ := ioutil.ReadAll(resp.Body) return string(content) } func GetIntranetIp() { addrs, err := net.InterfaceAddrs() if err != nil { fmt.Println(err) os.Exit(1) } for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { fmt.Println("ip: ", ipnet.IP.String()) } } } } func TaobaoAPI(ip string) *IPInfo { url := "http://ip.taobao.com/service/getIpInfo.php?ip=" url +=ip resp, err := http.Get(url) if err != nil { return nil } defer resp.Body.Close() out, err := ioutil.ReadAll(resp.Body) if err != nil { return nil } var result IPInfo if err := json.Unmarshal(out, &result); err != nil { return nil } return &result } func IPItoa(ipnr int64) net.IP { var bytes [4]byte bytes[0] = byte(ipnr & 0xff) bytes[1] = byte((ipnr >> 8) & 0xff) bytes[2] = byte((ipnr >> 16) & 0xff) bytes[3] = byte((ipnr >> 24) & 0xff) return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0]) } func IPAtoi(ipnr net.IP) int64 { bits := strings.Split(ipnr.String(), ".") b0, _ := strconv.Atoi(bits[0]) b1, _ := strconv.Atoi(bits[1]) b2, _ := strconv.Atoi(bits[2]) b3, _ := strconv.Atoi(bits[3]) var sum int64 sum += int64(b0) << 24 sum += int64(b1) << 16 sum += int64(b2) << 8 sum += int64(b3) return sum } func IpBetween(from net.IP, to net.IP, test net.IP) bool { if from == nil || to == nil || test == nil { fmt.Println("an ip input is nil") return false } from16 := from.To16() to16 := to.To16() test16 := test.To16() if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 { return true } return false } func IsPublicIP(ip net.IP) bool { if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() { return false } if ip4 := ip.To4(); ip4 != nil { switch true { case ip4[0] == 10: return false case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: return false case ip4[0] == 192 && ip4[1] == 168: return false } } return false } func GetPublicIP() string { conn, _ := net.Dial("udp","8.8.8.8:80") defer conn.Close() localAddr := conn.LocalAddr().String() idx := strings.LastIndex(localAddr,":") return localAddr[0:idx] } [root@master ~]#go run a.go pub ip: 218.240.128.48 cn 中国 city 华北 city 北京市 isp 电信 ip: 192.168.170.10 ip: 192.168.170.33 base 10: 3673194544 ipv4: 218.240.128.48 check: true public: false public ip: 192.168.170.10
参考文档:http://blog.csdn.net/wangshubo1989/article/details/78066344
–
–
–
评论前必须登录!
注册