Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 423|回复: 0

[默认分类] Go实战--golang中获取公网ip、查看内网ip、检测ip类型、校验ip区间、ip地址string和int转换、根据ip判断地区国家运营商等

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2016-1-2 10:36:35 | 显示全部楼层 |阅读模式

    生命不止,继续 go go go!!!
    之前,有介绍过golang提供的标准库:net包
    Go语言学习之net包(The way to go)
    简要回味net包
    func ParseIP
    1. [code]func ParseIP(s string) IP
    复制代码
    [/code]
    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
    1. [code]func InterfaceAddrs() ([]Addr, error)
    复制代码
    [/code]
    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.
    1. [code]type IPNet struct { IP IP // network number Mask IPMask // network mask }
    复制代码
    [/code]
    type IP
    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.
    1. [code]type IP []byte
    复制代码
    [/code]
    func IPv4
    1. [code]func IPv4(a, b, c, d byte) IP
    复制代码
    [/code]
    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
    1. [code]curl ipinfo.io/ip
    复制代码
    [/code]
    通过http://myexternalip.com/raw获取公网ip
    1. [code]func get_external() string {
    2.     resp, err := http.Get("http://myexternalip.com/raw")
    3.     if err != nil {
    4.         return ""
    5.     }
    6.     defer resp.Body.Close()
    7.     content, _ := ioutil.ReadAll(resp.Body)
    8.     //buf := new(bytes.Buffer)
    9.     //buf.ReadFrom(resp.Body)
    10.     //s := buf.String()
    11.     return string(content)
    12. }
    复制代码
    [/code]
    获取本地ip
    1. [code]func GetIntranetIp() {
    2.     addrs, err := net.InterfaceAddrs()
    3.     if err != nil {
    4.         fmt.Println(err)
    5.         os.Exit(1)
    6.     }
    7.     for _, address := range addrs {
    8.         // 检查ip地址判断是否回环地址
    9.         if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
    10.             if ipnet.IP.To4() != nil {
    11.                 fmt.Println("ip:", ipnet.IP.String())
    12.             }
    13.         }
    14.     }
    15. }
    复制代码
    [/code]
    通过dns服务器8.8.8.8:80获取使用的ip
    1. [code]func GetPulicIP() string {
    2.     conn, _ := net.Dial("udp", "8.8.8.8:80")
    3.     defer conn.Close()
    4.     localAddr := conn.LocalAddr().String()
    5.     idx := strings.LastIndex(localAddr, ":")
    6.     return localAddr[0:idx]
    7. }
    复制代码
    [/code]
    判断是否是公网ip
    1. [code]func IsPublicIP(IP net.IP) bool {
    2.     if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {
    3.         return false
    4.     }
    5.     if ip4 := IP.To4(); ip4 != nil {
    6.         switch true {
    7.         case ip4[0] == 10:
    8.             return false
    9.         case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
    10.             return false
    11.         case ip4[0] == 192 && ip4[1] == 168:
    12.             return false
    13.         default:
    14.             return true
    15.         }
    16.     }
    17.     return false
    18. }
    复制代码
    [/code]
    ip地址string转int
    1. [code]func inet_aton(ipnr net.IP) int64 {
    2.     bits := strings.Split(ipnr.String(), ".")
    3.     b0, _ := strconv.Atoi(bits[0])
    4.     b1, _ := strconv.Atoi(bits[1])
    5.     b2, _ := strconv.Atoi(bits[2])
    6.     b3, _ := strconv.Atoi(bits[3])
    7.     var sum int64
    8.     sum += int64(b0) << 24
    9.     sum += int64(b1) << 16
    10.     sum += int64(b2) << 8
    11.     sum += int64(b3)
    12.     return sum
    13. }
    复制代码
    [/code]
    ip地址int转string
    1. [code]func inet_ntoa(ipnr int64) net.IP {
    2.     var bytes [4]byte
    3.     bytes[0] = byte(ipnr & 0xFF)
    4.     bytes[1] = byte((ipnr >> 8) & 0xFF)
    5.     bytes[2] = byte((ipnr >> 16) & 0xFF)
    6.     bytes[3] = byte((ipnr >> 24) & 0xFF)
    7.     return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0])
    8. }
    复制代码
    [/code]
    判断ip地址区间
    1. [code]func IpBetween(from net.IP, to net.IP, test net.IP) bool {
    2.     if from == nil || to == nil || test == nil {
    3.         fmt.Println("An ip input is nil") // or return an error!?
    4.         return false
    5.     }
    6.     from16 := from.To16()
    7.     to16 := to.To16()
    8.     test16 := test.To16()
    9.     if from16 == nil || to16 == nil || test16 == nil {
    10.         fmt.Println("An ip did not convert to a 16 byte") // or return an error!?
    11.         return false
    12.     }
    13.     if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
    14.         return true
    15.     }
    16.     return false
    17. }
    复制代码
    [/code]
    通过淘宝接口根据公网ip获取国家运营商等信息
    接口:
    http://ip.taobao.com/service/getIpInfo.php?ip=
    1. [code]
    2. type IPInfo struct {
    3.     Code int `json:"code"`
    4.     Data IP  `json:"data`
    5. }
    6. type IP struct {
    7.     Country   string `json:"country"`
    8.     CountryId string `json:"country_id"`
    9.     Area      string `json:"area"`
    10.     AreaId    string `json:"area_id"`
    11.     Region    string `json:"region"`
    12.     RegionId  string `json:"region_id"`
    13.     City      string `json:"city"`
    14.     CityId    string `json:"city_id"`
    15.     Isp       string `json:"isp"`
    16. }
    17. func TabaoAPI(ip string) *IPInfo {
    18.     url := "http://ip.taobao.com/service/getIpInfo.php?ip="
    19.     url += ip
    20.     resp, err := http.Get(url)
    21.     if err != nil {
    22.         return nil
    23.     }
    24.     defer resp.Body.Close()
    25.     out, err := ioutil.ReadAll(resp.Body)
    26.     if err != nil {
    27.         return nil
    28.     }
    29.     var result IPInfo
    30.     if err := json.Unmarshal(out, &result); err != nil {
    31.         return nil
    32.     }
    33.     return &result
    34. }
    复制代码
    [/code]
    完整代码
    1. [code]package main
    2. import (
    3.     "bytes"
    4.     "encoding/json"
    5.     "fmt"
    6.     "io/ioutil"
    7.     "net"
    8.     "net/http"
    9.     "os"
    10.     "strconv"
    11.     "strings"
    12. )
    13. type IPInfo struct {
    14.     Code int `json:"code"`
    15.     Data IP  `json:"data`
    16. }
    17. type IP struct {
    18.     Country   string `json:"country"`
    19.     CountryId string `json:"country_id"`
    20.     Area      string `json:"area"`
    21.     AreaId    string `json:"area_id"`
    22.     Region    string `json:"region"`
    23.     RegionId  string `json:"region_id"`
    24.     City      string `json:"city"`
    25.     CityId    string `json:"city_id"`
    26.     Isp       string `json:"isp"`
    27. }
    28. func main() {
    29.     external_ip := get_external()
    30.     external_ip = strings.Replace(external_ip, "\n", "", -1)
    31.     fmt.Println("公网ip是: ", external_ip)
    32.     fmt.Println("------Dividing Line------")
    33.     ip := net.ParseIP(external_ip)
    34.     if ip == nil {
    35.         fmt.Println("您输入的不是有效的IP地址,请重新输入!")
    36.     } else {
    37.         result := TabaoAPI(string(external_ip))
    38.         if result != nil {
    39.             fmt.Println("国家:", result.Data.Country)
    40.             fmt.Println("地区:", result.Data.Area)
    41.             fmt.Println("城市:", result.Data.City)
    42.             fmt.Println("运营商:", result.Data.Isp)
    43.         }
    44.     }
    45.     fmt.Println("------Dividing Line------")
    46.     GetIntranetIp()
    47.     fmt.Println("------Dividing Line------")
    48.     ip_int := inet_aton(net.ParseIP(external_ip))
    49.     fmt.Println("Convert IPv4 address to decimal number(base 10) :", ip_int)
    50.     ip_result := inet_ntoa(ip_int)
    51.     fmt.Println("Convert decimal number(base 10) to IPv4 address:", ip_result)
    52.     fmt.Println("------Dividing Line------")
    53.     is_between := IpBetween(net.ParseIP("0.0.0.0"), net.ParseIP("255.255.255.255"), net.ParseIP(external_ip))
    54.     fmt.Println("check result: ", is_between)
    55.     fmt.Println("------Dividing Line------")
    56.     is_public_ip := IsPublicIP(net.ParseIP(external_ip))
    57.     fmt.Println("It is public ip: ", is_public_ip)
    58.     is_public_ip = IsPublicIP(net.ParseIP("169.254.85.131"))
    59.     fmt.Println("It is public ip: ", is_public_ip)
    60.     fmt.Println("------Dividing Line------")
    61.     fmt.Println(GetPulicIP())
    62. }
    63. func get_external() string {
    64.     resp, err := http.Get("http://myexternalip.com/raw")
    65.     if err != nil {
    66.         return ""
    67.     }
    68.     defer resp.Body.Close()
    69.     content, _ := ioutil.ReadAll(resp.Body)
    70.     buf := new(bytes.Buffer)
    71.     buf.ReadFrom(resp.Body)
    72.     //s := buf.String()
    73.     return string(content)
    74. }
    75. func GetIntranetIp() {
    76.     addrs, err := net.InterfaceAddrs()
    77.     if err != nil {
    78.         fmt.Println(err)
    79.         os.Exit(1)
    80.     }
    81.     for _, address := range addrs {
    82.         // 检查ip地址判断是否回环地址
    83.         if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
    84.             if ipnet.IP.To4() != nil {
    85.                 fmt.Println("ip:", ipnet.IP.String())
    86.             }
    87.         }
    88.     }
    89. }
    90. func TabaoAPI(ip string) *IPInfo {
    91.     url := "http://ip.taobao.com/service/getIpInfo.php?ip="
    92.     url += ip
    93.     resp, err := http.Get(url)
    94.     if err != nil {
    95.         return nil
    96.     }
    97.     defer resp.Body.Close()
    98.     out, err := ioutil.ReadAll(resp.Body)
    99.     if err != nil {
    100.         return nil
    101.     }
    102.     var result IPInfo
    103.     if err := json.Unmarshal(out, &result); err != nil {
    104.         return nil
    105.     }
    106.     return &result
    107. }
    108. func inet_ntoa(ipnr int64) net.IP {
    109.     var bytes [4]byte
    110.     bytes[0] = byte(ipnr & 0xFF)
    111.     bytes[1] = byte((ipnr >> 8) & 0xFF)
    112.     bytes[2] = byte((ipnr >> 16) & 0xFF)
    113.     bytes[3] = byte((ipnr >> 24) & 0xFF)
    114.     return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0])
    115. }
    116. func inet_aton(ipnr net.IP) int64 {
    117.     bits := strings.Split(ipnr.String(), ".")
    118.     b0, _ := strconv.Atoi(bits[0])
    119.     b1, _ := strconv.Atoi(bits[1])
    120.     b2, _ := strconv.Atoi(bits[2])
    121.     b3, _ := strconv.Atoi(bits[3])
    122.     var sum int64
    123.     sum += int64(b0) << 24
    124.     sum += int64(b1) << 16
    125.     sum += int64(b2) << 8
    126.     sum += int64(b3)
    127.     return sum
    128. }
    129. func IpBetween(from net.IP, to net.IP, test net.IP) bool {
    130.     if from == nil || to == nil || test == nil {
    131.         fmt.Println("An ip input is nil") // or return an error!?
    132.         return false
    133.     }
    134.     from16 := from.To16()
    135.     to16 := to.To16()
    136.     test16 := test.To16()
    137.     if from16 == nil || to16 == nil || test16 == nil {
    138.         fmt.Println("An ip did not convert to a 16 byte") // or return an error!?
    139.         return false
    140.     }
    141.     if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
    142.         return true
    143.     }
    144.     return false
    145. }
    146. func IsPublicIP(IP net.IP) bool {
    147.     if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {
    148.         return false
    149.     }
    150.     if ip4 := IP.To4(); ip4 != nil {
    151.         switch true {
    152.         case ip4[0] == 10:
    153.             return false
    154.         case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
    155.             return false
    156.         case ip4[0] == 192 && ip4[1] == 168:
    157.             return false
    158.         default:
    159.             return true
    160.         }
    161.     }
    162.     return false
    163. }
    164. func GetPulicIP() string {
    165.     conn, _ := net.Dial("udp", "8.8.8.8:80")
    166.     defer conn.Close()
    167.     localAddr := conn.LocalAddr().String()
    168.     idx := strings.LastIndex(localAddr, ":")
    169.     return localAddr[0:idx]
    170. }
    复制代码
    [/code]
    输出:
    1. [code]公网ip是:  222.128.17*.***
    2. ------Dividing Line------
    3. 国家: 中国
    4. 地区: 华北
    5. 城市: 北京市
    6. 运营商: 联通
    7. ------Dividing Line------
    8. ip: 169.254.85.131
    9. ip: 169.254.64.29
    10. ip: 169.254.211.178
    11. ip: 192.168.106.1
    12. ip: 192.168.154.1
    13. ip: 169.254.212.223
    14. ip: 192.168.10.26
    15. ip: 169.254.63.20
    16. ------Dividing Line------
    17. Convert IPv4 address to decimal number(base 10) : 373297****
    18. Convert decimal number(base 10) to IPv4 address: 222.128.17*.***
    19. ------Dividing Line------
    20. check result:  true
    21. ------Dividing Line------
    22. It is public ip:  true
    23. It is public ip:  false
    24. ------Dividing Line------
    25. 192.168.10.26
    复制代码
    [/code]


    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-7 03:05 , Processed in 0.416115 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表