Pergunta

I want to get the computer's IP address. I used the code below, but it returns 127.0.0.1.

I want to get the IP address, such as 10.32.10.111, instead of the loopback address.

name, err := os.Hostname()
if err != nil {
     fmt.Printf("Oops: %v\n", err)
     return
}

addrs, err := net.LookupHost(name)
if err != nil {
    fmt.Printf("Oops: %v\n", err)
    return
}

for _, a := range addrs {
    fmt.Println(a)
}  
Foi útil?

Solução 2

You need to loop through all network interfaces

ifaces, err := net.Interfaces()
// handle err
for _, i := range ifaces {
    addrs, err := i.Addrs()
    // handle err
    for _, addr := range addrs {
        var ip net.IP
        switch v := addr.(type) {
        case *net.IPNet:
                ip = v.IP
        case *net.IPAddr:
                ip = v.IP
        }
        // process IP address
    }
}

Play (taken from util/helper.go)

Outras dicas

Here is a better solution to retrieve the preferred outbound ip address when there are multiple ip interfaces exist on the machine.

import (
    "log"
    "net"
    "strings"
)

// Get preferred outbound ip of this machine
func GetOutboundIP() net.IP {
    conn, err := net.Dial("udp", "8.8.8.8:80")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    localAddr := conn.LocalAddr().(*net.UDPAddr)

    return localAddr.IP
}

To ensure that you get a non-loopback address, simply check that an IP is not a loopback when you are iterating.

// GetLocalIP returns the non loopback local IP of the host
func GetLocalIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        return ""
    }
    for _, address := range addrs {
        // check the address type and if it is not a loopback the display it
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }
    return ""
}

net.LookupHost() on your os.Hostname() is probably always going to give you 127.0.0.1, because that's what's in your /etc/hosts or equivalent.

I think what you want to use is net.InterfaceAddrs():

func InterfaceAddrs() ([]Addr, error)

InterfaceAddrs returns a list of the system's network interface addresses.

This worked for me:

host, _ := os.Hostname()
addrs, _ := net.LookupIP(host)
for _, addr := range addrs {
    if ipv4 := addr.To4(); ipv4 != nil {
        fmt.Println("IPv4: ", ipv4)
    }   
}

Unlike the poster's example, it returns only non-loopback addresses, e.g. 10.120.X.X.

func GetInternalIP() string {
    itf, _ := net.InterfaceByName("enp1s0") //here your interface
    item, _ := itf.Addrs()
    var ip net.IP
    for _, addr := range item {
        switch v := addr.(type) {
        case *net.IPNet:
            if !v.IP.IsLoopback() {
                if v.IP.To4() != nil {//Verify if IP is IPV4
                    ip = v.IP
                }
            }
        }
    }
    if ip != nil {
        return ip.String()
    } else {
        return ""
    }
}
func resolveHostIp() (string) {

    netInterfaceAddresses, err := net.InterfaceAddrs()

    if err != nil { return "" }

    for _, netInterfaceAddress := range netInterfaceAddresses {

        networkIp, ok := netInterfaceAddress.(*net.IPNet)

        if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil {

            ip := networkIp.IP.String()

            fmt.Println("Resolved Host IP: " + ip)

            return ip
        }
    }
    return ""
}

If you only have one IP address except 127.0.0.1, You can check the code down here.

conn,err := net.Dial("ip:icmp","google.com")
fmt.Println(conn.LocalAddr())

The second parameter can be any IP address except 127.0.0.1

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top