sniffer 项目地址: https://github.com/chenjiandongx/sniffer
在 Linux 系统中,进程的多数指标数据都能在 /proc/${PID} 路径下获取到,但网络 IO 的数据,比如网络流量或者进出网络包吞吐量这类的是没有办法直接读取到的。一番搜索后,在 Github 上找到两个工具,imsnif/bandwhich 和 raboof/nethogs,前者使用 Rust 编写,后者使用 C++ 编写。bandwhich 界面精巧并且支持以多种视角查看流量数据,像 Socket 连接、进程以及远程端点,但不支持传入 BPF 过滤条件,比如只想查看某个端口的流量数据或者过滤某个 IP 的数据。而 nethlogs 支持 BPF 过滤条件但只能以进程维度查看数据。
那问题就来了,能不能两者兼得呢?既能使用 BPF 过滤特性又能以多种视角查看数据。
当然可以,自己动手写一个不就行了。
chenjiandongx/sniffer 是一个 Golang 编写的,支持 TCP/UDP 协议,用于查看分析进程或者连接的流量情况的命令行工具。既然要查看进程流量,那如何高效的将网络包的信息将进程信息关联起来就显得十分重要了。在 sniffer 中,Linux 系统下使用的是类似 ss 命令的 netlink socket ,只获取 ESTABLISHED 状态的连接,而不是直接读取 /proc/net/* 下面的数据,这种做法更高效,因为主机上可能存在大量的 TimeWait 的链接,这些链接是不会有流量的,所以无需纳入统计范围内。而 MacOS 上则用的是 losf 命令,也是仅获取 ESTABLISHED 状态的连接。Windows 上就比较简单粗暴了,直接使用 shirou/gopsutil 提供的 API 。
❯ sniffer -h
# A modern alternative network traffic sniffer.
Usage:
sniffer [flags]
Examples:
# processes mode for pid 1024,2048 in MB unit
$ sniffer -p 1024 -p 2048 -m 2 -u MB
# only capture the TCP protocol packets with lo,eth prefixed devices
$ sniffer -b tcp -d lo -d eth
Flags:
-b, --bpf string specify string pcap filter with the BPF syntax (default "tcp or udp")
-d, --devices-prefix stringArray prefixed devices to monitor (default [en,lo,eth,em,bond])
-h, --help help for sniffer
-i, --interval int interval for refresh rate in seconds (default 1)
-l, --list list all devices name
-m, --mode int view mode of sniffer (0: bytes 1: packets 2: processes)
-n, --no-dns-resolve disable the DNS resolution
-p, --pids int32Slice pids to watch, empty stands for all pids (default [])
-u, --unit string unit of traffic stats in processes mode, optional: B, KB, MB, GB (default "KB")
-v, --version version for sniffer
Bytes Mode: 以流量视角查看数据
Packets Mode: 以网络包视角渲染数据。
Processes Mode: 进程整体维度展示数据。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.