golang获取本机IP(带缓存)

带缓存版:

package main

import (
	"bytes"
	"fmt"
	"net"
	"os"
	"strings"
	"sync"
	"time"
)

var ipCacheMap sync.Map
var ipCacheMapTimeout = 10 * time.Minute

type IpCacheMapValue struct {
	Ip string
	Ts time.Time
}

func main() {
	ipv4, err := GetLocalIP("")
	fmt.Printf("ipv4=%v err=%v\n", ipv4, err)
}

func GetLocalIP(ipPrefix string) (ipv4 string, err error) {
	var defaultIface string
	if ipPrefix == "" {
		bs, err := os.ReadFile("/proc/net/route")
		if err != nil {
			return "", err
		}
		lines := bytes.Split(bs, []byte{'\n'})
		defaultDestination := []byte("00000000")
		for _, line := range lines {
			line = bytes.Trim(line, "\r\t ")
			if len(line) == 0 {
				continue
			}
			parts := bytes.Split(line, []byte{'\t'})
			if len(parts) < 3 || bytes.Compare(parts[1], defaultDestination) != 0 {
				continue
			}
			defaultIface = string(parts[0])
			break
		}
	}
	ipVal, ok := ipCacheMap.Load(ipPrefix)
	if ok {
		ipInfo, ok := ipVal.(IpCacheMapValue)
		if ok && time.Now().Before(ipInfo.Ts.Add(ipCacheMapTimeout)) {
			return ipInfo.Ip, nil
		}
	}
	var (
		addrs   []net.Addr
		ifaces  []net.Interface
		addr    net.Addr
		ipNet   *net.IPNet
		isIpNet bool
	)
	ifaces, err = net.Interfaces()
	if err != nil {
		return
	}
	for _, iface := range ifaces {
		if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
			continue
		}
		if ipPrefix == "" && iface.Name != defaultIface {
			continue
		}
		addrs, err = iface.Addrs()
		if err != nil {
			continue
		}
		for _, addr = range addrs {
			if ipNet, isIpNet = addr.(*net.IPNet); isIpNet && !ipNet.IP.IsLoopback() {
				// 跳过IPV6
				if ipNet.IP.To4() != nil {
					ipv4 = ipNet.IP.String() // 192.168.1.1
					if ipPrefix != "" && !strings.HasPrefix(ipv4, ipPrefix) {
						continue
					}
					ipCacheMap.Store(ipPrefix, IpCacheMapValue{Ip: ipv4, Ts: time.Now()})
					return
				}
			}
		}
	}
	err = fmt.Errorf("get local ip fail")
	return
}

--end--

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值