手把手写C++服务器:Linux四大必备网络分析工具
Posted 沉迷单车的追风少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手写C++服务器:Linux四大必备网络分析工具相关的知识,希望对你有一定的参考价值。
前言:Linux命令浩如烟海、多如牛毛,但是针对服务器编程,必学的四大网络分析工具:ping、tcpdump、netstat和lsof,为后面编程、调试、分析、运维打下基础。其中ping和netstat是linux、Unix、windows系统所共有的,可以我之前的一篇文章:Windows奇技淫巧之网络命令行
目录
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字符
表达式中重要关键字
- 类型关键字。host——指明主机,net——指明网络地址,port——指明端口号;默认关键字是host。
- 传输方向关键字。src——源地址,dst——目标地址,src or dst——源地址或目标地址;默认关键字是src or dst。
- 协议关键字。fddi——分布式光纤数据接口网络,arp、tcp、udp等协议,这些非常熟悉了,不详解;默认关键字是监听所有协议的数据包。
- 逻辑运算关键字。非——not/!,与——and/&&,或——or/||。
- 其他关键字,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
可以看出,输出结果分成两部分:
- Active Internet connections (w/o servers):有源TCP连接,Recv-Q表示接收队列,Send-Q表示发送队列,数字一般为0,不为0则表示请求包和返回包正在队列中堆积。
- 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
参考:
- 《Linux多线程服务端编程》
- 《Linux高性能服务器编程》
- 《后台开发核心技术与应用实践》
- https://blog.csdn.net/qq_27870421/article/details/92803453
- https://www.jianshu.com/p/a3aa6b01b2e1
- https://blog.csdn.net/lgh1117/article/details/80213397
以上是关于手把手写C++服务器:Linux四大必备网络分析工具的主要内容,如果未能解决你的问题,请参考以下文章
手把手写C++服务器(21):Linux socket网络编程入门基础
手把手写C++服务器(14):基于UDP测量两台机器之间的网络延迟
手把手写C++服务器(22):Linux socket网络编程进阶第一弹
手把手写C++服务器(22):Linux socket网络编程进阶第一弹