package netstat import ( "bufio" "fmt" "os" "strings" "time" ) // InterfaceStats 网卡统计信息 type InterfaceStats struct { Name string //网卡名称 RxBytes uint64 //接收字节数 TxBytes uint64 //发送字节数 RxPackets uint64 //接收数据包数 TxPackets uint64 //发送数据包数 RxErrors uint64 //接收错误数 TxErrors uint64 //发送错误数 } type TrafficRate struct { Name string // 网卡名称 RxBytesRate float64 // 接收字节速率 TxBytesRate float64 // 发送字节速率 RxKbps float64 // 接收比特速率 TxKbps float64 // 发送比特速率 } // GetInterfaceStats 获取所有网卡的统计信息 func GetInterfaceStats() ([]InterfaceStats, error) { // 打开/proc/net/dev文件 file, err := os.Open("/proc/net/dev") if err != nil { return nil, err } defer file.Close() // 创建scanner逐行读取文件内容 scanner := bufio.NewScanner(file) // 跳过前两行 头部信息 scanner.Scan() scanner.Scan() var stats []InterfaceStats for scanner.Scan() { line := scanner.Text() // 按空格分割 fields := strings.Fields(line) if len(fields) < 17 { continue } // 提取网卡名 ifaceName := strings.TrimSuffix(fields[0], ":") if ifaceName == "lo" { continue //跳过回环接口 } stat := InterfaceStats{ Name: ifaceName, RxBytes: parseUint64(fields[1]), RxPackets: parseUint64(fields[2]), RxErrors: parseUint64(fields[3]), TxBytes: parseUint64(fields[9]), TxPackets: parseUint64(fields[10]), TxErrors: parseUint64(fields[11]), } stats = append(stats, stat) } return stats, scanner.Err() } func parseUint64(s string) uint64 { var val uint64 fmt.Sscanf(s, "%d", &val) return val } func CalculateRate(prev, curr []InterfaceStats, duration time.Duration) []TrafficRate { prevMap := make(map[string]InterfaceStats) for _, stat := range prev { prevMap[stat.Name] = stat } var rates []TrafficRate seconds := duration.Seconds() for _, c := range curr { p, exists := prevMap[c.Name] if !exists { continue } rxBytesDiff := c.RxBytes - p.RxBytes txBytesDiff := c.TxBytes - p.TxBytes rate := TrafficRate{ Name: c.Name, RxBytesRate: float64(rxBytesDiff) / seconds, TxBytesRate: float64(txBytesDiff) / seconds, RxKbps: (float64(rxBytesDiff) * 8) / (seconds * 1024), TxKbps: (float64(txBytesDiff) * 8) / (seconds * 1024), } rates = append(rates, rate) } return rates } func FormatBytes(bytes float64) string { const unit = 1024 if bytes < unit { return fmt.Sprintf("%.2f B", bytes) } div, exp := uint64(unit), 0 for n := bytes / unit; n >= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf("%.2f %cB", bytes/float64(div), "KMGTPE"[exp]) } // FormatBps 格式化比特率为 1.23 Kbps、4.56 Mbps 等 func FormatBps(bps float64) string { const unit = 1000 if bps < unit { return fmt.Sprintf("%.2f bps", bps) } div, exp := float64(unit), 0 for n := bps / unit; n >= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf("%.2f %cps", bps/div, "KMGTPE"[exp]) }