Linux 网络编程 调试工具

来源:互联网 发布:二手车 知乎 编辑:程序博客网 时间:2024/05/17 23:25

这篇说一下用于网络编程的两个调试工具,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 

 

还有更高级的应用,后面用到会继续补上

 

0 0