手把手写C++服务器:Linux四大必备网络分析工具

Posted 沉迷单车的追风少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手写C++服务器:Linux四大必备网络分析工具相关的知识,希望对你有一定的参考价值。

前言:Linux命令浩如烟海、多如牛毛,但是针对服务器编程,必学的四大网络分析工具:ping、tcpdump、netstat和lsof,为后面编程、调试、分析、运维打下基础。其中ping和netstat是linux、Unix、windows系统所共有的,可以我之前的一篇文章:Windows奇技淫巧之网络命令行

 目录

1、ping

命令格式

 应用举例:六步法检查网络连通性

2、tcpdump

命令格式

参数详解

表达式中重要关键字

应用举例1:截取指定主机所有数据包

应用举例2:截取某端口上的包

 应用举例3:截取指定网卡上的包

3、netstat

命令格式

常用参数

显示解析

应用举例1:列出所有监听端口和未监听端口

应用举例2:列出所有TCP端口

应用举例3:列出所有UDP端口

应用举例4:只显示监听端口

应用举例5:输出中显示PID和进程名称

应用举例6:  显示所有端口的统计信息

应用举例7:列出所有监听的TCP/UDP/UNIX端口

应用举例8:持续输出 netstat 信息

应用举例9:显示核心路由信息

4、lsof

命令格式

常用参数

应用举例1:默认情况显示所有进程打开的所有文件

应用举例2:查看某端口现在的运行情况

应用举例3:查看指定用户进程所打开指定类型的文件

应用举例4:查看指定设备被进程占用的情况

应用举例5:查看指定程序打开的文件

应用举例6:查看指定用户打开的文件

参考:


1、ping

ping全称Packet Internet Groper,因特网探索包,发送一个ICMP,请求消息给目的地并报告是否收到所希望的ICMP echo,用来检查网络是否畅通和网络连接的速度。

注意:ping是一个端到端连接,通常用来进行网路可用性检查,但是大量的ping会占用大量的网络资源和系统资源,因此是黑客入侵防火墙的基本手段之一。

Linux下ping的语法和windows差不多,但是Linux的ping数据包时64Bytes,windows的是32Bytes,windows下默认发送4次数据包后结束,Linux下ping程序默认不停发送数据包,用Ctrl+c停止运行。

命令格式

 ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination
 ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination

 应用举例:六步法检查网络连通性

(1)ifconfig检查本地网络设置是否正确,查看本机IP

(2)ping localhost(ping 127.0.0.1)检查本地TCP/IP协议是否设置正确

(3)ping本机IP地址,检查本机IP地址是否设置正确

(4)ping局域网下其他地址,检查局域网是否有问题

(5)ping本地DNS地址,检查本地DNS服务是否正常工作

先查看本机DNS地址:

cat /etc/resolv.conf

会显示主DNS和备用DNS,直接ping即可。通过ping本地DNS地址,可以检查本地DNS服务器是否正常

(6)ping远程地址

用来检查本机与外部连接是否正常,同时也可以测试网络延时。

ping www.baidu.com

2、tcpdump

tcpdump是一款经典开源的网络抓包工具,对标wireshark,支持对主机、协议、网络、端口的过滤,并提供and、or、not等语句过滤。但是ubuntu默认没有安装tcpdump软件,通过apt-get install tcpdump安装即可。

命令格式

tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ]

     [ -i 网络接口 ] [ -r 文件名] [ -s snaplen ]

        [ -T 类型 ] [ -w 文件名 ] [表达式 ]

 其中表达式支持正则表达式,强大的正则帮助我们过滤出我需要的需要的数据包。在表达式中有几类关键字,后面详细介绍。

 tcpdump [-aAbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ]
                [ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]
                [ -i interface ] [ -j tstamptype ] [ -M secret ] [ --number ]
                [ -Q in|out|inout ]
                [ -r file ] [ -s snaplen ] [ --time-stamp-precision precision ]
                [ --immediate-mode ] [ -T type ] [ --version ] [ -V file ]
                [ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]
                [ -Z user ] [ expression ]

参数详解

  • -a    将网络地址和广播地址转变成名字;
  • -d    将匹配信息包的代码以人们能够理解的汇编格式给出;
  • -dd    将匹配信息包的代码以c语言程序段的格式给出;
  • -ddd     将匹配信息包的代码以十进制的形式给出;
  • -e    显示以太网帧头部信息
  • -f     将外部的Internet地址以数字的形式打印出来;
  • -l     使标准输出变为缓冲行形式;
  • -n    指定将每个监听到数据包中的域名转换成IP地址后显示,不把网络地址转换成名字;
  • -nn          指定将每个监听到的数据包中的域名转换成IP、端口从应用名称转换成端口号后显示
  • -t     在输出的每一行不打印时间戳
  • -v       输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
  • -vv     输出详细的报文信息;
  • -c    在收到指定的包的数目后,tcpdump就会停止(仅抓取指定数量的数据包)
  • -F    从指定的文件中读取表达式,忽略其它的表达式;
  • -i     指定监听的网络接口,“-i any”表示住区所有网卡接口上的数据包
  • -p           将网卡设置为非混杂模式,不能与host或broadcast一起使用
  • -r    从指定的文件中读取包(这些包一般通过-w选项产生);
  • -w     直接将包写入文件中,并不分析和打印出来;
  • -s           设置抓包时的抓取长度。0表示包不截断,抓完整的数据包。默认的话 tcpdump 只显示部分数据包,默认68字节。4.0版本后,默认长度变成65535。
  • -S           以绝对值来显示TCP报文段的序号,而不是相对值。
  • -T      将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)
  • -x            以十六进制显示数据包的内容,但不显示以太网帧的头部信息
  • -X           和-x类似,不过还打印每个十六进制字节对应的ASCII字符

表达式中重要关键字

  1. 类型关键字。host——指明主机,net——指明网络地址,port——指明端口号;默认关键字是host。
  2. 传输方向关键字。src——源地址,dst——目标地址,src or dst——源地址或目标地址;默认关键字是src or dst。
  3. 协议关键字。fddi——分布式光纤数据接口网络,arp、tcp、udp等协议,这些非常熟悉了,不详解;默认关键字是监听所有协议的数据包。
  4. 逻辑运算关键字。非——not/!,与——and/&&,或——or/||。
  5. 其他关键字,gateway——网关,broadcast——广播,less——少于,greater——多于。

应用举例1:截取指定主机所有数据包

tcpdump host 10.38.31.230

应用举例2:截取某端口上的包

tcpdump port 6666

 应用举例3:截取指定网卡上的包

tcpdump -i eth1

配合其他关键字可以轻松实现指定两个主机之间通信的数据包、指定tcp/ip之间的数据包等等,就不一一举例了。

3、netstat

用于显示IP、TCP、UDP和ICMP相关协议的统计数据,一般用于检测本机各端口的网络连接情况。

命令格式

 netstat [-vWeenNcCF] [<Af>] -r         netstat {-V|--version|-h|--help}
       netstat [-vWnNcaeol] [<Socket> ...]
       netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }

常用参数

-a(all)显示所有选项,默认不显示LISTEN相关
-t(tcp)仅显示tcp相关选项
-u(udp)仅显示udp相关选项
-n拒绝显示别名,能显示数字的全部转化成数字。
-l仅列出有在 Listen (监听) 的服務状态
-p显示建立相关链接的程序名
-r显示路由信息,路由表
-e显示扩展信息,例如uid等
-s按各个协议进行统计
-c每隔一个固定时间,执行该netstat命令。

完整参数:

        -r, --route              display routing table
        -i, --interfaces         display interface table
        -g, --groups             display multicast group memberships
        -s, --statistics         display networking statistics (like SNMP)
        -M, --masquerade         display masqueraded connections

        -v, --verbose            be verbose
        -W, --wide               don't truncate IP addresses
        -n, --numeric            don't resolve names
        --numeric-hosts          don't resolve host names
        --numeric-ports          don't resolve port names
        --numeric-users          don't resolve user names
        -N, --symbolic           resolve hardware names
        -e, --extend             display other/more information
        -p, --programs           display PID/Program name for sockets
        -o, --timers             display timers
        -c, --continuous         continuous listing

        -l, --listening          display listening server sockets
        -a, --all                display all sockets (default: connected)
        -F, --fib                display Forwarding Information Base (default)
        -C, --cache              display routing cache instead of FIB
        -Z, --context            display SELinux security context for sockets

显示解析

执行默认netstat命令后,会显示:

netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0    200 c3c21a5a34d1:ssh        10.38.31.230:59876      ESTABLISHED
tcp        0      0 c3c21a5a34d1:ssh        10.38.31.230:59627      ESTABLISHED
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags       Type       State         I-Node   Path

可以看出,输出结果分成两部分:

  1. Active Internet connections (w/o servers):有源TCP连接,Recv-Q表示接收队列Send-Q表示发送队列,数字一般为0,不为0则表示请求包和返回包正在队列中堆积。
  2. Active UNIX domain sockets (w/o servers):有源UNIX域套接口。每一列的参数含义一次如下:
    proto连接所使用的协议
    RefCnt连接到本套接口上的进程号
    Types套接口类型
    State套接口当前状态
    Path连接到套接口的其他进程所使用的路径名

应用举例1:列出所有监听端口和未监听端口

netstat -a

应用举例2:列出所有TCP端口

netstat -at

应用举例3:列出所有UDP端口

netstat -au

应用举例4:只显示监听端口

netstat -l

应用举例5:输出中显示PID和进程名称

netstat -p

应用举例6:  显示所有端口的统计信息

netstat -s

应用举例7:列出所有监听的TCP/UDP/UNIX端口

netstat -lt
netstat -lu
netstat -lx

应用举例8:持续输出 netstat 信息

netstat 将每隔一秒输出网络信息。

netstat -c

应用举例9:显示核心路由信息

netstat -r

4、lsof

list of file,列出当前系统打开文件的工具。在Linux当中,万物皆文件!任何事物都是以文件形式存在的

命令格式

 [-?abhKlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-E] [+|-e s] [+|-f[gG]]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
 [+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]

常用参数

-a表示两个参数都满足时候才能显示结果
-c<进程名>表示COMMON列中必须包含指定字符的进程所有打开的文件
-u username显示所属username打开的文件
-g gid显示归属gid进程的情况
-d显示指定文件描述符的进程
-i显示符合条件的进程的情况
+d<目录>显示目录下被进程打开的文件
-v显示版本信息
-p<进程号> 列出指定进程号所打开的文件
-h显示帮助信息

应用举例1:默认情况显示所有进程打开的所有文件

lsof
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
bash        1 root  cwd    DIR              0,301     4096 158630055 /
bash        1 root  rtd    DIR              0,301     4096 158630055 /
bash        1 root  txt    REG              0,301  1113504 151191557 /bin/bash
bash        1 root  mem    REG              253,0          151191557 /bin/bash (path dev=0,301)
bash        1 root  mem    REG              253,0          151191941 /lib/x86_64-linux-gnu/libnss_files-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191935 /lib/x86_64-linux-gnu/libnsl-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191945 /lib/x86_64-linux-gnu/libnss_nis-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191937 /lib/x86_64-linux-gnu/libnss_compat-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191899 /lib/x86_64-linux-gnu/libc-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191909 /lib/x86_64-linux-gnu/libdl-2.27.so (path dev=0,301)
bash        1 root  mem    REG              253,0          151191979 /lib/x86_64-linux-gnu/libtinfo.so.5.9 (path dev=0,301)
bash        1 root  mem    REG              253,0          151191881 /lib/x86_64-linux-gnu/ld-2.27.so (path dev=0,301)

依次解释各列的参数含义:

  • COMMAD:进程名称
  • PID:进程标识符
  • USER:进程所有者
  • FD:文件描述符,应用程序通过文件描述符识别该文件
  • TYPE:文件类型
  • DEVICE:指定磁盘名称
  • SIZE:文件大小
  • NODE:打开文件的确切名称

应用举例2:查看某端口现在的运行情况

lsof -i :54758
COMMAND   PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
sshd    22431 root    3u  IPv4 687393234      0t0  TCP c3c21a5a34d1:ssh->10.38.31.230:54758 (ESTABLISHED)

应用举例3:查看指定用户进程所打开指定类型的文件

比如查看查看root所打开txt文件:

lsof -a -u root -d txt

应用举例4:查看指定设备被进程占用的情况

比如查看/dev/null 被那些进程占用:

lsof /dev/null
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash        1 root    0u   CHR    1,3      0t0    6 /dev/null
sshd       16 root    0u   CHR    1,3      0t0    6 /dev/null
sshd       16 root    1u   CHR    1,3      0t0    6 /dev/null
sshd       16 root    2u   CHR    1,3      0t0    6 /dev/null
screen   7666 root    0r   CHR    1,3      0t0    6 /dev/null
screen   7666 root    1w   CHR    1,3      0t0    6 /dev/null
screen   7666 root    2w   CHR    1,3      0t0    6 /dev/null
sshd    22431 root    0u   CHR    1,3      0t0    6 /dev/null
sshd    22431 root    1u   CHR    1,3      0t0    6 /dev/null
sshd    22431 root    2u   CHR    1,3      0t0    6 /dev/null
screen  22640 root    0r   CHR    1,3      0t0    6 /dev/null
screen  22640 root    1w   CHR    1,3      0t0    6 /dev/null
screen  22640 root    2w   CHR    1,3      0t0    6 /dev/null
screen  23229 root    0r   CHR    1,3      0t0    6 /dev/null
screen  23229 root    1w   CHR    1,3      0t0    6 /dev/null
screen  23229 root    2w   CHR    1,3      0t0    6 /dev/null
sshd    23352 root    0u   CHR    1,3      0t0    6 /dev/null
sshd    23352 root    1u   CHR    1,3      0t0    6 /dev/null
sshd    23352 root    2u   CHR    1,3      0t0    6 /dev/null
sleep   23394 root    0u   CHR    1,3      0t0    6 /dev/null
screen  27125 root    0r   CHR    1,3      0t0    6 /dev/null
screen  27125 root    1w   CHR    1,3      0t0    6 /dev/null
screen  27125 root    2w   CHR    1,3      0t0    6 /dev/null

应用举例5:查看指定程序打开的文件

比如查看screen程序打开的文件:

 lsof -c screen
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
screen   7666 root  cwd    DIR              0,247     4096  97591500 /root/Multi-view (10.106.128.106:/mnt/nfs/userdata/2/17020710009)
screen   7666 root  rtd    DIR              0,301     4096 158630055 /
screen   7666 root  txt    REG              0,301   465928 158663915 /usr/bin/screen
screen   7666 root  mem    REG              253,0          158663915 /usr/bin/screen (path dev=0,301)

应用举例6:查看指定用户打开的文件

比如查看root用户打开的文件:

lsof -u root

参考:

以上是关于手把手写C++服务器:Linux四大必备网络分析工具的主要内容,如果未能解决你的问题,请参考以下文章

手把手写C++服务器(21):Linux socket网络编程入门基础

手把手写C++服务器(14):基于UDP测量两台机器之间的网络延迟

手把手写C++服务器(22):Linux socket网络编程进阶第一弹

手把手写C++服务器(22):Linux socket网络编程进阶第一弹

手把手写C++服务器(38):面试必背!Linux网络socket编程必会十问!

手把手写C++服务器(20):网络字节序与主机字节序大端小端与共用体