netstat是一個非常實用的socket查看命令。但是有人留言它已經被ss(Socket Statistics)替代了,那麼這個所謂替代netstat的命令,到底怎麼用呢?爲什麼它能替代netstat?
爲什麼使用ss
值得注意的是,幾乎所有的linux系統都默認支持netstat命令,而並不一定支持ss,從這一點來說,netstat通常還是不二選擇。但是不得不承認的是,ss命令更加快捷高效。
netstat從proc文件系統獲取所需要的信息,而ss利用netlink機制,與內核通信,通過TCP 協議棧中 tcp_diag 模塊獲取第一手的內核信息。當然這些都不是我們關注的重點,我們來看看ss命令到底如何使用。
查看TCP/UDP連接
使用-t(TCP)參數查看TCP連接,而使用-u(UDP)參數查看UDP socket:
$ ss -t
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.0.103:56296 113.107.216.82:https
ESTAB 0 0 192.168.0.103:56540 185.199.108.153:https
ESTAB 0 0 127.0.0.1:socks 127.0.0.1:44452
ESTAB 0 0 127.0.0.1:42150 127.0.0.1:9614
其中state顯示了當前連接的狀態,例如結果的第一行是ESTABLISHED狀態,Local Address:port代表本地連接的ip和端口號。另外使用-n參數顯示數字形式的ip和端口。
查看socket進程信息
查看到某個連接後,怎麼知道是哪個進程的連接呢?使用-p(processes)即可,例如:
$ ss -tp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 127.0.0.1:42150 127.0.0.1:9614 users:(("chrome",pid=2578,fd=347))
ESTAB 0 0 127.0.0.1:41910 127.0.0.1:9614 users:(("chrome",pid=2578,fd=383))
拖動滾動條到最後可以看到,-p參數顯示了這條連接的進程信息,例如,對於第一條結果,可以看到,該進程是chrome,進程id爲2578,並且這條連接的文件描述符爲383。
查看處於特定狀態的socket
我們知道,對於TCP連接來講,在不同的階段它的狀態不同,常見狀態有
ESTABLISHED 已建立
CLOSED 已關閉
LISTENING 正在監聽
FIN-WAIT-2 等待連接關閉
TIME-WAIT 等待足夠時間,確保服務器正常關閉該連接
……
這裏還有很多其他狀態,我們會留到介紹TCP的時候展開。
如何查看處於特定狀態的連接呢?例如,要查看處於LISTENING狀態的連接:
$ ss -t state LISTENING
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 5 127.0.1.1:domain *:*
0 128 127.0.0.1:5941 *:*
0 5 127.0.0.1:ipp *:*
使用state選項即可查看。當然對於LISTENING狀態,也可以使用-l參數。
除此之外,還有以下參數,用於查看某類狀態,例如:
all 所有類型
connected 除closed和listen狀態以外已連接的狀態
synchronized 除了syn-sent外的狀態
查看TCP相關定時器信息
我們知道在TCP中,有很多定時器,和netstat一樣,可以使用-o參數顯示定時器相關信息:
$ ss -to
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 127.0.0.1:44660 127.0.0.1:socks timer:(keepalive,4min42sec,0)
ESTAB 0 0 192.168.0.103:60306 203.208.41.37:https timer:(keepalive,9.956ms,0)
ESTAB 0 0
例如上面顯示的keepalive定時器剩餘時間:
timer:(keepalive,9.956ms,0)
查看socket詳細信息
如果想要查看連接更加詳細信息呢?比如收到多少數據?上一個ACK是什麼時候?mss是多大?擁塞窗口大小是多少?這些信息在分析理解TCP的時候非常有幫助,而查看這些信息只需要使用-i(information)參數即可:
$ ss -ti #(內容很長,省略了很多信息,可執行嘗試)
cubic wscale:7,7 rto:204 rtt:2.302/4.528 ato:40 mss:23488 cwnd:10 bytes_acked:1560 bytes_received:3907 segs_out:18 segs_in:20 send 816.3Mbps lastsnd:1384 lastrcv:1384 lastack:1384 pacing_rate 1632.1Mbps rcv_rtt:546 rcv_space:43690
由於顯示的內容比較多,這裏就不貼出來了,可自行嘗試,裏面展示了TCP很多關鍵信息。
查看socket內存使用情況
使用-m(memory)參數可以查看連接使用內存信息:
$ ss -tm #只顯示內存部分信息
skmem:(r0,rb374400,t0,tb46080,f0,w0,o0,bl0)
由於信息較多,這裏只顯示內存部分,括號內從左到右分別代表:
接收報文分配的內存
接收報文可分配的內存
發送報文分配的內存
發送報文可分配的內存
socket使用的緩存
爲將要發送的報文分配的內存
保存socket選項使用的內存
連接隊列使用的內存
顯示socket統計信息
使用-s(summary)查看整體統計信息
$ ss -s
Total: 1379 (kernel 2907)
TCP: 68 (estab 58, closed 1, orphaned 0, synrecv 0, timewait 1/0), ports 0
Transport Total IP IPv6
* 2907 - -
RAW 1 0 1
UDP 13 8 5
TCP 67 47 20
INET 81 55 26
FRAG 0 0 0
從統計結果中可以看到,共有67個TCP連接。