Linux 網絡編程 調試工具


  這篇說一下用於網絡編程的兩個調試工具,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 

 

還有更高級的應用,后面用到會繼續補上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM