如何获取当前机器的地址?

huangapple go评论85阅读模式
英文:

How to retrieve address of current machine?

问题

以下是获取本地IP地址的代码:

package main

import (
    "fmt"
    "net"
)

func main() {
    a, _ := net.LookupHost("localhost")
    fmt.Printf("Addresses: %#+v\n",a)
}

这是您通常获取本地IP地址的方式吗?根据需要手动筛选切片?

英文:

The following grabs the local IP addresses:

package main

import (
    "fmt"
    "net"
)

func main() {
    a, _ := net.LookupHost("localhost")
    fmt.Printf("Addresses: %#+v\n",a)
}

Is this how you would normally get the local IP address, filtering the slice manually according to need?

答案1

得分: 4

这是对原始代码片段的一个快速而简单的修改,最初是由Russ Cox在golang-nuts google组中发布的:

package main

import (
	"fmt"
	"net"
	"os"
)

func main() {
	tt, err := net.Interfaces()
	if err != nil {
		panic(err)
	}
	for _, t := range tt {
		aa, err := t.Addrs()
		if err != nil {
			panic(err)
		}
		for _, a := range aa {
			ipnet, ok := a.(*net.IPNet)
			if !ok {
				continue
			}
			v4 := ipnet.IP.To4()
			if v4 == nil || v4[0] == 127 { // loopback address
				continue
			}
			fmt.Printf("%v\n", v4)
		}
		os.Exit(0)
	}
	os.Exit(1)
}
英文:

Here's a quick and dirty modification of a code snippet originally posted by Russ Cox to the golang-nuts google group:

package main

import (
  "fmt" 
  "net" 
  "os"  
)

func main() {
  tt, err := net.Interfaces()
  if err != nil { 
    panic(err)  
  }     
  for _, t := range tt {
    aa, err := t.Addrs()
    if err != nil {
      panic(err)        
    }           
    for _, a := range aa {
      ipnet, ok := a.(*net.IPNet) 
      if !ok {          
        continue                
      }                 
      v4 := ipnet.IP.To4() 
      if v4 == nil || v4[0] == 127 { // loopback address
        continue                
      }                 
      fmt.Printf("%v\n", v4)
    }           
    os.Exit(0)  
  }     
  os.Exit(1)

}

答案2

得分: 1

寻找正确的IP地址可能会成为一个问题,因为一个典型的服务器和开发机可能有多个接口。例如,在我的Mac上运行$ifconfig命令会返回以下接口:lo0, gif0, stf0, en0, en1, en2, bridge0, p2p0, vmnet1, vmnet8, tap0, fw0, en4

基本上,你需要了解你的环境。

虽然不太美观,但以下是我在生产环境的Ubuntu服务器上使用的代码。它也适用于我的开发环境Mac 10.9.2,不知道在Windows上会发生什么。

package main

import (
	"net"
	"strings"
)

func findIPAddress() string {
	if interfaces, err := net.Interfaces(); err == nil {
		for _, interfac := range interfaces {
			if interfac.HardwareAddr.String() != "" {
				if strings.Index(interfac.Name, "en") == 0 ||
					strings.Index(interfac.Name, "eth") == 0 {
					if addrs, err := interfac.Addrs(); err == nil {
						for _, addr := range addrs {
							if addr.Network() == "ip+net" {
								pr := strings.Split(addr.String(), "/")
								if len(pr) == 2 && len(strings.Split(pr[0], ".")) == 4 {
									return pr[0]
								}
							}
						}
					}
				}
			}
		}
	}
	return ""
}

func main() {
	println(findIPAddress())
}
英文:

Finding the correct IP address can be a problem because a typical server and development machine may have multiple interfaces. For example $ifconfig on my Mac returns the following interfaces lo0, gif0, stf0, en0, en1, en2, bridge0, p2p0, vmnet1, vmnet8, tap0, fw0, en4

Basically, you need to know your environment.

It's not pretty, but for what it's worth, this is what I use on a production Ubuntu server. It also works on my development Mac 10.9.2, who know what it does on Windows.

package main

import (
	"net"
	"strings"
)

func findIPAddress() string {
	if interfaces, err := net.Interfaces(); err == nil {
		for _, interfac := range interfaces {
			if interfac.HardwareAddr.String() != "" {
				if strings.Index(interfac.Name, "en") == 0 ||
					strings.Index(interfac.Name, "eth") == 0 {
					if addrs, err := interfac.Addrs(); err == nil {
						for _, addr := range addrs {
							if addr.Network() == "ip+net" {
								pr := strings.Split(addr.String(), "/")
								if len(pr) == 2 && len(strings.Split(pr[0], ".")) == 4 {
									return pr[0]
								}
							}
						}
					}
				}
			}
		}
	}
	return ""
}

func main() {
	println(findIPAddress())
}

答案3

得分: 1

我有一个补充:上面显示的当前解决方案在FreeBSD 10上至少不起作用,因为系统以CIDR表示法返回地址,例如192.168.1.2/32!因此,需要稍微修改解决方案:

package main

import (
    "fmt"
    "net"
    "os"
    "strings"
)

func main() {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        fmt.Println("错误:" + err.Error())
        os.Exit(1)
    }

    for _, a := range addrs {
        text := a.String()

        if strings.Contains(text, "/") {
            text = text[:strings.Index(text, "/")]
        }

        ip := net.ParseIP(text)
        if !ip.IsLoopback() && !ip.IsUnspecified() {
            fmt.Println(ip)
        }
    }
}

部分代码...

if strings.Contains(text, "/") {
    text = text[:strings.Index(text, "/")]
}

...检测地址中是否包含/,并删除该部分!

最好的祝福,

Thorsten

英文:

I have one addition: The current solutions shown above are not working at least on FreeBSD 10 because the system returns the addresses as CIDR notation e.g. 192.168.1.2/32! Therefore, it is necessary to change the solution a little bit:

package main

import (
    "fmt"
    "net"
    "os"
    "strings"
)

func main() {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        fmt.Println("Error: " + err.Error())
        os.Exit(1)
    }

    for _, a := range addrs {
        text := a.String()

        if strings.Contains(text, `/`) {
            text = text[:strings.Index(text, `/`)]
        }

        ip := net.ParseIP(text)
        if !ip.IsLoopback() && !ip.IsUnspecified() {
            fmt.Println(ip)
        }
    }
}

The part ...

if strings.Contains(text, `/`) {
    text = text[:strings.Index(text, `/`)]
}

... detects if / is part of the address and delete this part!

Best regards,

Thorsten

答案4

得分: 0

这是一个Go语言的代码片段,它用于获取本机的IP地址。以下是翻译好的代码:

package main

import (
	"fmt"
	"net"
	"os"
)

func myip() {
	os.Stdout.WriteString("我的IP地址:\n")

	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Errorf("错误: %v\n", err.Error())
		return
	}

	for _, a := range addrs {
		ip := net.ParseIP(a.String())
		fmt.Printf("地址: %v 回环=%v\n", a, ip.IsLoopback())
	}

	fmt.Println()
}

func myip2() {
	os.Stdout.WriteString("我的IP地址2:\n")

	tt, err := net.Interfaces()
	if err != nil {
		fmt.Errorf("错误: %v\n", err.Error())
		return
	}
	for _, t := range tt {
		aa, err := t.Addrs()
		if err != nil {
			fmt.Errorf("错误: %v\n", err.Error())
			continue
		}
		for _, a := range aa {
			ip := net.ParseIP(a.String())
			fmt.Printf("%v 地址: %v 回环=%v\n", t.Name, a, ip.IsLoopback())
		}
	}

	fmt.Println()
}

func main() {
	fmt.Println("获取IP地址 -- 开始")
	myip()
	myip2()
	fmt.Println("获取IP地址 -- 结束")
}

这段代码通过调用net包中的函数来获取本机的IP地址,并打印出来。函数myip()使用net.InterfaceAddrs()函数获取IP地址列表,函数myip2()使用net.Interfaces()函数获取网络接口列表,并通过循环获取每个接口的IP地址。最后,在main()函数中调用这两个函数并打印输出。

英文:

These slight modifications worked for me:

package main

import (
	"fmt"
	"net"
	"os"
)

func myip() {
	os.Stdout.WriteString("myip:\n")

	addrs, err := net.InterfaceAddrs()
	if err != nil {
 		fmt.Errorf("error: %v\n", err.Error())
 		return
	}

	for _, a := range addrs {
		ip := net.ParseIP(a.String())
		fmt.Printf("addr: %v loopback=%v\n", a, ip.IsLoopback())
	}

	fmt.Println()
}

func myip2() {
	os.Stdout.WriteString("myip2:\n")

	tt, err := net.Interfaces()
	if err != nil {
		fmt.Errorf("error: %v\n", err.Error())
		return
	}
	for _, t := range tt {
		aa, err := t.Addrs()
		if err != nil {
			fmt.Errorf("error: %v\n", err.Error())
			continue
		}
		for _, a := range aa {
			ip := net.ParseIP(a.String())
			fmt.Printf("%v addr: %v loopback=%v\n", t.Name, a, ip.IsLoopback())
		}
	}

	fmt.Println()
}

func main() {
	fmt.Println("myip -- begin")
	myip()
	myip2()
	fmt.Println("myip -- end")
}

huangapple
  • 本文由 发表于 2014年4月8日 15:36:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/22930510.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定