简介
为了更方便的使用,我们将实现一个可以扫描本地连接网络中可用连接的扫描功能, 扫描本地连接网络中有哪些连接的设备主机。
环境描述
运行环境 : Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端:树莓派DebianOS(主要做用它测试)
实现
go
package utils
import (
"net"
)
type NetworkInterface struct {
Name string // interface name
IPv4 string
IPv6 string
}
func GetLocalActivityNetworkInterfaces() ([]NetworkInterface, error) {
var (
networkInterfaces = make([]NetworkInterface, 0)
tempNetworkInterface NetworkInterface
err error
interfaces []net.Interface
tempAddrs []net.Addr
)
interfaces, err = net.Interfaces()
if err != nil {
return nil, err
}
for _, iface := range interfaces {
//fmt.Println("ifaceName: ", iface.Name, ", flags: ", iface.Flags)
// 过滤掉蓝牙和未连接的网络接口
if !isActivityNetwork(iface.Flags) {
continue
}
tempNetworkInterface.Name = iface.Name
tempAddrs, err = iface.Addrs()
if err != nil {
continue
}
for _, addr := range tempAddrs {
// 只处理IP地址
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
tempNetworkInterface.IPv4 = ipnet.IP.String()
} else if ipnet.IP.To16() != nil {
tempNetworkInterface.IPv6 = ipnet.IP.String()
}
}
}
networkInterfaces = append(networkInterfaces, tempNetworkInterface)
}
return networkInterfaces, nil
}
func isActivityNetwork(flags net.Flags) bool {
return !isActivityNetworkUnnecessary(flags) && isActivityNetworkNecessary(flags)
}
func isActivityNetworkNecessary(flags net.Flags) bool {
var fliterFlags = []net.Flags{
net.FlagUp, net.FlagRunning, net.FlagBroadcast, net.FlagMulticast,
}
for _, flg := range fliterFlags {
if 0 == (flg & flags) {
return false
}
}
return true
}
func isActivityNetworkUnnecessary(flags net.Flags) bool {
var fliterFlags = []net.Flags{
net.FlagPointToPoint, net.FlagLoopback,
}
for _, flg := range fliterFlags {
if 0 != (flg & flags) {
return true
}
}
return false
}
测试用例
go
package utils
import (
"fmt"
"testing"
)
func TestGetLocalActivityNetworkInterfaces(t *testing.T) {
var interfaces, err = GetLocalActivityNetworkInterfaces()
if nil != err {
fmt.Println("get lcoal activity network fail, ", err.Error())
return
}
for _, intf := range interfaces {
fmt.Printf("InterfaceName: %s, IPv4: %s, IPv6: %s.\n", intf.Name, intf.IPv4, intf.IPv6)
}
}
代码源
https://gitee.com/grayhsu/ssh_remote_access