Go 本機私有IPv4地址獲取代碼

通過以下代碼獲取本機私有IPv4地址

方一:

package main

import (
    "net"
    "fmt"
)

func main(){
    addrs,_ := GetPrivateIPv4()
    for _,addr :=range addrs {
        println(addr.String())
    }

}

// privateBlocks contains non-forwardable address blocks which are used
// for private networks. RFC 6890 provides an overview of special
// address blocks.
var privateBlocks = []*net.IPNet{
    parseCIDR("10.0.0.0/8"),     // RFC 1918 IPv4 private network address
    parseCIDR("100.64.0.0/10"),  // RFC 6598 IPv4 shared address space
    parseCIDR("127.0.0.0/8"),    // RFC 1122 IPv4 loopback address
    parseCIDR("169.254.0.0/16"), // RFC 3927 IPv4 link local address
    parseCIDR("172.16.0.0/12"),  // RFC 1918 IPv4 private network address
    parseCIDR("192.0.0.0/24"),   // RFC 6890 IPv4 IANA address
    parseCIDR("192.0.2.0/24"),   // RFC 5737 IPv4 documentation address
    parseCIDR("192.168.0.0/16"), // RFC 1918 IPv4 private network address
    parseCIDR("::1/128"),        // RFC 1884 IPv6 loopback address
    parseCIDR("fe80::/10"),      // RFC 4291 IPv6 link local addresses
    parseCIDR("fc00::/7"),       // RFC 4193 IPv6 unique local addresses
    parseCIDR("fec0::/10"),      // RFC 1884 IPv6 site-local addresses
    parseCIDR("2001:db8::/32"),  // RFC 3849 IPv6 documentation address
}


func parseCIDR(s string) *net.IPNet {
    _, block, err := net.ParseCIDR(s)
    if err != nil {
        panic(fmt.Sprintf("Bad CIDR %s: %s", s, err))
    }
    return block
}

func GetPrivateIPv4() ([]*net.IPAddr, error) {
    addresses, err := activeInterfaceAddresses()
    if err != nil {
        return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
    }

    var addrs []*net.IPAddr
    for _, rawAddr := range addresses {
        var ip net.IP
        switch addr := rawAddr.(type) {
        case *net.IPAddr:
            ip = addr.IP
        case *net.IPNet:
            ip = addr.IP
        default:
            continue
        }
        if ip.To4() == nil {
            continue
        }

        if !isPrivate(ip) {
            continue
        }
        addrs = append(addrs, &net.IPAddr{IP: ip})
    }
    return addrs, nil
}

// Returns addresses from interfaces that is up
func activeInterfaceAddresses() ([]net.Addr, error) {
    var upAddrs []net.Addr
    var loAddrs []net.Addr

    interfaces, err := net.Interfaces()
    if err != nil {
        return nil, fmt.Errorf("Failed to get interfaces: %v", err)
    }

    for _, iface := range interfaces {
        // Require interface to be up
        if iface.Flags&net.FlagUp == 0 {
            continue
        }

        addresses, err := iface.Addrs()
        if err != nil {
            return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
        }

        if iface.Flags&net.FlagLoopback != 0 {
            loAddrs = append(loAddrs, addresses...)
            continue
        }

        upAddrs = append(upAddrs, addresses...)
    }

    if len(upAddrs) == 0 {
        return loAddrs, nil
    }

    return upAddrs, nil
}

func isPrivate(ip net.IP) bool {
    for _, priv := range privateBlocks {
        if priv.Contains(ip) {
            return true
        }
    }
    return false
}

方二:

func GetNoLoopbackAddr() string {
    ifaces, err := net.Interfaces()
    if err != nil {
        panic(err)
    }
    for _, iface := range ifaces {
        if (iface.Flags&net.FlagUp == net.FlagUp) && (iface.Flags&net.FlagLoopback != net.FlagLoopback) && (iface.Flags&net.FlagPointToPoint != net.FlagPointToPoint) {
            addrs, err := iface.Addrs()
            if err != nil {
                panic(err)
            }
            for _, addr := range addrs {

                if ipAddr, ok := addr.(*net.IPNet); ok {
                    ipV4 := ipAddr.IP.To4()
                    if ipV4 != nil {
                        return ipV4.String()
                    }
                }

                if ipAddr, ok := addr.(*net.IPAddr); ok {
                    ipV4 := ipAddr.IP.To4()
                    if ipV4 != nil {
                        return ipV4.String()
                    }
                }
            }
        }
    }
    return ""
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砚尽,一起剝皮案震驚了整個濱河市挪捕,隨后出現(xiàn)的幾起案子湿刽,更是在濱河造成了極大的恐慌鱼辙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件事示,死亡現(xiàn)場離奇詭異熟丸,居然都是意外死亡豫尽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門吼砂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逆航,“玉大人,你說我怎么就攤上這事渔肩∫蚶” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵周偎,是天一觀的道長抹剩。 經(jīng)常有香客問我,道長蓉坎,這世上最難降的妖魔是什么澳眷? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮袍嬉,結(jié)果婚禮上境蔼,老公的妹妹穿的比我還像新娘灶平。我一直安慰自己,他們只是感情好箍土,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布逢享。 她就那樣靜靜地躺著,像睡著了一般吴藻。 火紅的嫁衣襯著肌膚如雪瞒爬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天沟堡,我揣著相機與錄音侧但,去河邊找鬼。 笑死航罗,一個胖子當(dāng)著我的面吹牛禀横,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播粥血,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼柏锄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了复亏?” 一聲冷哼從身側(cè)響起趾娃,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缔御,沒想到半個月后抬闷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡耕突,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年笤成,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片有勾。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡疹启,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔼卡,到底是詐尸還是另有隱情喊崖,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布雇逞,位于F島的核電站荤懂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏塘砸。R本人自食惡果不足惜节仿,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掉蔬。 院中可真熱鬧廊宪,春花似錦矾瘾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至傅寡,卻和暖如春放妈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荐操。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工芜抒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人托启。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓宅倒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親驾中。 傳聞我的和親對象是個殘疾皇子唉堪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351