package main import ( "os" "os/exec" "strconv" "strings" "time" ) // readNetworkInterfaces 读取网络接口信息(包含瞬时流量速度) - 优化版:所有接口并行采样 func readNetworkInterfaces() []NetworkInterface { interfaces := []NetworkInterface{} // 读取网络接口列表 entries, err := os.ReadDir("/sys/class/net") if err != nil { return interfaces } // 收集要监控的接口名称 var validIfaces []string for _, entry := range entries { ifName := entry.Name() if ifName == "lo" { // 跳过回环接口 continue } // 跳过 Docker 相关网络接口 if strings.HasPrefix(ifName, "docker") || strings.HasPrefix(ifName, "br-") || strings.HasPrefix(ifName, "veth") { continue } validIfaces = append(validIfaces, ifName) } // 第一次批量读取所有接口的流量 firstReadings := make(map[string][2]uint64) // [rx, tx] for _, ifName := range validIfaces { rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes" txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes" var rxBytes, txBytes uint64 if rxStr := readFirstLine(rxPath); rxStr != "" { rxBytes, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64) } if txStr := readFirstLine(txPath); txStr != "" { txBytes, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64) } firstReadings[ifName] = [2]uint64{rxBytes, txBytes} } // 等待500ms(所有接口一起等待,而不是每个接口单独等待) time.Sleep(500 * time.Millisecond) // 第二次批量读取并构建结果 for _, ifName := range validIfaces { iface := NetworkInterface{ Name: ifName, } // 读取 MAC 地址 macPath := "/sys/class/net/" + ifName + "/address" iface.MACAddress = strings.TrimSpace(readFirstLine(macPath)) // 读取 IP 地址 (使用 ip addr show) cmd := exec.Command("ip", "addr", "show", ifName) if out, err := cmd.Output(); err == nil { lines := strings.Split(string(out), "\n") for _, line := range lines { line = strings.TrimSpace(line) if strings.HasPrefix(line, "inet ") { fields := strings.Fields(line) if len(fields) >= 2 { iface.IPAddress = strings.Split(fields[1], "/")[0] break } } } } // 读取第二次流量统计 rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes" txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes" var rxBytes2, txBytes2 uint64 if rxStr := readFirstLine(rxPath); rxStr != "" { rxBytes2, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64) } if txStr := readFirstLine(txPath); txStr != "" { txBytes2, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64) } // 设置累计流量 iface.RxBytes = rxBytes2 iface.TxBytes = txBytes2 // 计算瞬时速度 (bytes/s,乘以2因为采样间隔是0.5秒) if first, ok := firstReadings[ifName]; ok { iface.RxSpeed = float64(rxBytes2-first[0]) * 2 iface.TxSpeed = float64(txBytes2-first[1]) * 2 } interfaces = append(interfaces, iface) } return interfaces }