需求:Python 監控特定 PID 的網絡流量。Python 無現成庫,參考 nethogs (C++) 實現原理。
進程打開的文件描述符位於 /proc/,Socket 表現為符號鏈接指向 socket:[inode]:
ls -l /proc/7140/fd/lrwx------ 1 user user 64 Jan 1 00:00 4 -> socket:[23045]lrwx------ 1 user user 64 Jan 1 00:00 5 -> socket:[23046] 提取 inode:23045, 23046。
內核導出 /proc/net/tcp (及 tcp6/udp/udp6),每行含 inode 字段:
cat /proc/net/tcp sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode... 0: 0100007F:1F90 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 5416572 1 ffff8800... 23045... 匹配 inode 即得 本地IP:端口 <-> 遠端IP:端口 及協議狀態。
IP 總長度 統計上下行字節數。/proc 解析 + libpcap 回調)。processNet):pip install processNet 或 GitHub 源碼。import processNetmonitor = processNet.ProcessMonitor(pid=7140)for stats in monitor.iter_stats(interval=1): print(f"PID {stats.pid}: RX={stats.rx_bytes} TX={stats.tx_bytes}") | 方案 | 優點 | 缺點 |
|---|---|---|
/proc/net/dev + 進程關聯 | 無需抓包,開銷極低 | 內核不導出「進程-流量」直接映射 |
cgroups net_cls + tc | 內核級精確控制 | 配置複雜,需 root,不適合臨時監控 |
| eBPF (BCC/bpftrace) | 可編程、無損、內核態聚合 | 需內核 4.1+,學習曲線陡峭 |
| libpcap 旁路 (本文方案) | 用戶態實現、跨版本兼容 | 高流量下 CPU 佔用高、需 root、無法捕獲本地回環 |
生產環境建議優先考慮 eBPF 方案(如 bpftrace -e 'tracepoint:net:net_dev_xmit /pid==1234/ @[comm]=count()')。