在 Linux 系統中,若要針對**單一進程**統計網路流量(而非整張網卡),需結合封包擷取與進程資訊對應。本文詳細說明核心步驟與關鍵命令。
使用 libpcap 擷取封包,解析五元組(來源 IP、目的 IP、來源埠、目的埠、協定號)與封包大小,建立會話流量表,隨著通訊持續累加位元組數。
每個進程的 /proc/ 目錄下,符號連結指向 socket:[inode]。遍歷所有進程,建立 PID → {inode 列表} 對應表。
# 取得 PID ps aux | grep firefox # 假設 PID 為 2143 # 查看該進程持有的 socket inode ls -l /proc/2143/fd/ | grep socket # 輸出範例: # lrwx------ 1 user user 64 Nov 19 11:19 10 -> socket:[27273] # lrwx------ 1 user user 64 Nov 19 20:48 101 -> socket:[3726782] # ...
/proc/net/tcp 記錄當前 TCP 連線,欄位包含來源/目的位址、埠號、狀態、inode 等。將步驟 1 的五元組與此處比對,找出對應連線的 inode,再對應步驟 2 的進程表,即可歸屬流量至特定 PID。
cat /proc/net/tcp # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode # 0: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12396 # 1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11404 # ... # 16: 9707A8C0:EAFE DF08A8C0:0050 08 00000000:00000001 00:00000000 00000000 1000 0 2102209 # ...
欄位說明:
-local_address/rem_address:十六進位 IP:Port(小端序)
-st:連線狀態(01=ESTABLISHED, 06=TIME_WAIT 等)
-inode:Socket inode,可對應進程
#!/bin/bash # 簡易示範:列出指定 PID 的網路連線與流量估算 PID=$1 if [ -z "$PID" ]; then echo "Usage: $0"; exit 1; done # 1. 取得該 PID 所有 socket inode INODES=$(ls -l /proc/$PID/fd/ 2>/dev/null | grep -o 'socket:\[[0-9]*\]' | sed 's/socket:\[\([0-9]*\)\]/\1/') # 2. 對應 /proc/net/tcp 找出連線 echo "PID $PID 網路連線:" for inode in $INODES; do awk -v ino="$inode" '$10 == ino {printf " inode=%s local=%s remote=%s state=%s\n", ino, $2, $3, $4}' /proc/net/tcp done
tcplife、tcptop,核心級追蹤,效能最佳掌握 /proc/、/proc/net/tcp 與封包擷取的對應關係,是實作進程級流量監控的基礎。生產環境建議使用成熟工具(nethogs、bcc)以減少開發成本與效能負擔。