這篇說一下用於網絡編程的兩個調試工具,netstat和tcpdump
(一)netstat
先看一下手冊
NAME
netstat - Print network connections, routing tables, interface statis‐
tics, masquerade connections, and multicast memberships
常見參數
-a (all)顯示所有選項,默認不顯示LISTEN相關
-t (tcp)僅顯示tcp相關選項
-u (udp)僅顯示udp相關選項
-n 拒絕顯示別名,能顯示數字的全部轉化成數字。
-l 僅列出有在 Listen (監聽) 的服務狀態
-p 顯示建立相關鏈接的程序名
-r 顯示路由信息,路由表
-e 顯示擴展信息,例如uid等
-s 按各個協議進行統計
-c 每隔一個固定時間,執行該netstat命令。
提示:LISTEN和LISTENING的狀態只有用-a或者-l才能看到
netstat可以查看網絡端點的狀態,就好像這樣:
找出運行在指定端口的進程
netstat -an | grep ':80'
客戶端和服務器正在通信時(客戶端的socket 127.0.0.1:42490)
lei@ubuntu:~$ netstat -an | grep ':8080'
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8080 127.0.0.1:42490 ESTABLISHED
tcp 0 0 127.0.0.1:42490 127.0.0.1:8080 ESTABLISHED
客戶端正常退出后
lei@ubuntu:~$ netstat -an | grep ':8080'
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8080 127.0.0.1:42490 TIME_WAIT
這樣就可以方便地觀察客戶端與服務器的連接狀態,知道程序是否有錯
(二)tcpdump
DESCRIPTION
Tcpdump prints out a description of the contents of packets on a net‐
work interface that match the boolean expression.
使用tcpdump來抓包(這里我只說抓tcp包的情況)
通常tcpdump對tcp數據包的顯示格式如下:
src > dst: flags data-seqno ack window urgent options
src 和 dst 是源和目的IP地址以及相應的端口. flags 標志由S(SYN), F(FIN), P(PUSH, R(RST),
W(ECN CWT(nt | rep:未知, 需補充))或者 E(ECN-Echo(nt | rep:未知, 需補充))組成,
單獨一個'.'表示沒有flags標識.
監視指定網絡接口的數據包
tcpdump -i eth1
如果不指定網卡,默認tcpdump只會監視第一個網絡接口,一般是eth0,下面的例子指定網絡接口lo。
監視指定主機和端口的數據包
如果想要獲取主機端口為8080接收或發出的包,使用如下命令
(sudo是用root的權限運行)
sudo tcpdump -i lo tcp port 8080
(lo是什么呢,使用ifconfig命令可以看到
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:75 errors:0 dropped:0 overruns:0 frame:0
TX packets:75 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4337 (4.3 KB) TX bytes:4337 (4.3 KB)
)
以下是監視程序在運行時傳輸數據的情況
(1)建立連接
lei@ubuntu:~$ sudo tcpdump -i lo tcp port 8080
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes
19:43:45.788995 IP localhost.45867 > localhost.http-alt: Flags [S], seq 2913516689, win 32792, options [mss 16396,sackOK,TS val 491508 ecr 0,nop,wscale 6], length 0
19:43:45.789017 IP localhost.http-alt > localhost.45867: Flags [S.], seq 2915754001, ack 2913516690, win 32768, options [mss 16396,sackOK,TS val 491508 ecr 491508,nop,wscale 6], length 0
19:43:45.789040 IP localhost.45867 > localhost.http-alt: Flags [.], ack 1, win 513, options [nop,nop,TS val 491508 ecr 491508], length 0
(這是程序運行時客戶端與服務器連接時傳輸的數據,可以看到剛好有三個包,我想就是tcp建立連接時握手要用到的三個包)
(2)傳輸數據
然后我用客戶端給服務器發一個字符串“client”(這里可以看到有localhost.http-alt > localhost.45867的報文,
這是因為tcp的確認重傳機制,接收方要發送一個確認報文,同時也可以看到長度為6==“client”的長度)
19:58:45.002150 IP localhost.45867 > localhost.http-alt: Flags [P.], seq 18:24, ack 1, win 513, options [nop,nop,TS val 716312 ecr 716312], length 6
19:58:45.002164 IP localhost.http-alt > localhost.45867: Flags [.], ack 24, win 512, options [nop,nop,TS val 716312 ecr 716312], length 0
然后服務器發回給客戶端
19:58:45.002182 IP localhost.http-alt > localhost.45867: Flags [P.], seq 1:7, ack 24, win 512, options [nop,nop,TS val 716312 ecr 716312], length 6
19:58:45.002208 IP localhost.45867 > localhost.http-alt: Flags [.], ack 7, win 513, options [nop,nop,TS val 716312 ecr 716312], length 0
(3)關閉連接
客戶端發送退出信息“exit”(這個只是我在程序里面的設定)
20:02:45.854015 IP localhost.45867 > localhost.http-alt: Flags [P.], seq 24:28, ack 7, win 513, options [nop,nop,TS val 776525 ecr 716312], length 4
服務器確認退出,發送“user_exit"(這個只是我在程序里面的設定)
20:02:45.854155 IP localhost.http-alt > localhost.45867: Flags [P.], seq 7:16, ack 28, win 512, options [nop,nop,TS val 776525 ecr 776525], length 9
釋放連接(tcp釋放連接要用四個報文)
20:02:45.854188 IP localhost.http-alt > localhost.45867: Flags [F.], seq 16, ack 28, win 512, options [nop,nop,TS val 776525 ecr 776525], length 0
20:02:45.854300 IP localhost.45867 > localhost.http-alt: Flags [.], ack 16, win 513, options [nop,nop,TS val 776525 ecr 776525], length 0
20:02:45.854724 IP localhost.45867 > localhost.http-alt: Flags [F.], seq 28, ack 17, win 513, options [nop,nop,TS val 776525 ecr 776525], length 0
20:02:45.854754 IP localhost.http-alt > localhost.45867: Flags [.], ack 29, win 512, options [nop,nop,TS val 776525 ecr 776525], length 0
/*********************
* 新增內容
* 新增日期:2013-12-10
**********************/
tcpdump進階
最近用到的tcpdump的參數有
-A Print each packet (minus its link level header) in ASCII. Handy for capturing web pages.
-c Exit after receiving count packets.
-x Print each packet (minus its link level header) in hex. The smaller of the entire packet or snaplen bytes will be printed. Note that this is the entire
link-layer packet, so for link layers that pad (e.g. Ethernet), the padding bytes will also be printed when the higher layer packet is shorter than the
required padding.-xx Print each packet, including its link level header, in hex.
另外tcpdump還支持更復雜的指定主機、端口、源、目的地的選項
(1)想要截獲所有某主機收到的和發出的所有的數據包:
tcpdump host 210.135.25.46
(2)截獲所有某主機+主機某些端口收到的和發出的所有的數據包(以16進制和ascii形式打印出來):
sudo tcpdump -XX host 210.135.25.46 and \(port 48323 or port 58795\)
復雜的條件可以and、or、()的組合表示出來(注意括號前要加上\)
(3)指定發送源、目的端口或ip
使用src、dst關鍵字
截獲所有某主機+主機某些端口發出的所有的數據包
sudo tcpdump host 210.135.25.46 and src port 48323
還有更高級的應用,后面用到會繼續補上