目录
C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(专栏文章已更新460多篇,持续更新中...)https://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_2276111.html 无论是开发人员,还是测试人员,亦或是技术支持、运维人员等,在日常工作中都会遇到这样那样的网络问题(基于网络的软件系统可能会因为网络问题出现故障或者业务异常),都需要掌握抓网络数据包分析问题的技能。通过抓包分析,可以查看交互双方的具体数据内容以及数据是否存在异常,也可以确定业务交互流程是否正确完整,也可以排查各种网络故障。今天我们就来详细地讲讲常用的抓包工具、抓包分析的网络场景、分析抓包时的多种过滤条件以及如何结合常用的协议去分析排查问题,给大家提供一个借鉴或参考。
1、软件为什么会出现各式各样的网络问题?
几乎所有的软件系统都是基于网络运行的,要么是B/S架构的,要么是C/S架构的,比如PC端的客户端软件(例如QQ、PC版微信、腾讯会议等)和手机端的移动APP软件(例如淘宝、京东、手机QQ等),都是通过网络,和远端的后台服务器进行交互的。客户端从后台服务器拿取到数据,在客户端上展现出来,同时可以在客户端软件上做些修改或操作,这些修改的数据则保存到远端的服务器上。
这样,软件在运行过程中难免会出现各式各样与网络相关的问题,有些问题可能是软件本身的bug引发的,有些问题可能是复杂的网络环境导致的。有可能网络本身出故障,比如网络不通或者有明显的网络丢包(网络抖动、不稳定)。也有可能软件在特定的网络环境中无法正常运行,比如:
1)可能端口需要放行
客户网络环境安全级别比较高,默认情况下很多端口会被拦截,需要事先将软件用到的端口放行。
2)可能IP会和MAC地址绑定
客户网络环境比较复杂,安全级别比较高,会将IP和MAC地址绑定起来。一旦IP和MAC地址不一致,就会被拦截。设备入网运行时,要事先处理好IP和MAC地址的绑定。
3)可能网络中启用了重定向
这个案例我们在实际项目中遇到过,客户网络环境中启用了重定向的功能,但我们的硬件设备处于安全考虑,设备中的Linux系统TCPIP协议栈的重定向选项全部被关闭了,导致设备无法响应网络设备发来的ICMP重定向消息,所有数据还是从设定的默认网关发出来了,但从默认网关出去的链路很不稳定,有明显的网络抖动和丢包问题。应该要从重定向消息中指定的地址通道走出去的
之前针对平时面试时常问的网络问题,详细地总结了一篇网络入门的文章(入门篇),可以参看:
【网络入门】详解常用的基础网络知识(面试笔试常考内容)https://blog.csdn.net/chenlycly/article/details/124433936
同时根据项目中遇到的实际问题,写了一篇网络问题排查实例集锦(进阶篇),有一定的实战参考价值:
【网络进阶】网络问题排查实例集锦(实战经验分享)https://blog.csdn.net/chenlycly/article/details/124643918 无论是开发人员,还是测试人员,亦或是技术支持、运维人员等,在日常工作中都会遇到这样那样的网络问题,都需要掌握抓网络数据包分析问题的技能,这已经成为一个IT人员的必备技能。
2、Wireshark抓包工具与tcpdump命令
在Windows平台上,可以直接使用Wireshark软件抓包分析即可。在Linux平台(比如嵌入式设备和服务器设备)上,则需要使用tcpdump命令将网络包抓到文件中,然后使用FTP或者SSH工具将文件下载到Windows机器上,再使用Wireshark打开抓包文件分析。
对于Linux下的tcpdump命令,看一个完整的例子:
tcpdump -i eth0 -s 0 -w xmmpserver2.pcap tcp port 9222
其中:
-i eth0:表示抓取名为eth0的网卡上的包;
-s 0:表示不限制包的大小;
-w xmmpserver2.pcap:表示将抓取的包保存到xmmpserver2.pcap文件中,
tcp:表示只抓TCP包,
port 9222:表示抓取9222端口上的包(包括源端口是9222的包,也包括目标端口是9222的包)。
对于Linux设备的抓包,一般需要先用SSH软件登录到Linux系统,然后在命令行中执行tcpdump命令就可以了。
3、典型的网络场景下如何抓包
为了排查问题的需要,有时我们需要抓取不同网络设备上的包,最常见的是抓机器某网卡上的数据包。除了网卡,我们在某些场景下可能还要抓取路由器、集线器、交换机、加密机和防火墙设备上的数据包。下面根据项目中遇到的问题实战,对这些抓包场景进行一个大概的总结。
3.1、网卡
一般情况下,软件系统出问题了,会首先在客户端或服务器的网卡上抓包分析。这是最常见的一种抓包场景。
3.2、集线器
集线器的机制是每一个口的数据包都会广播给所有的网口,因此只需要将工作PC接入集线器就可以抓到流经集线器的所有数据包。
3.3、交换机
因为交换机内部已经有了转发规则,因此一般来说,如果数据包是从Ethernet 1 转发给Ethernet 2的话,将工作PC接到Ethernet 3\4\5…上并不能抓到该数据包。
然而,因为交换机在网络中广泛分布,为了排查网络故障,常常需要抓取经过交换机某网口的数据包,因此部分厂商推出了镜像端口的功能,可以在交换机中设置该端口为某一端口的镜像,此时被镜像的端口就会将流经该端口的数据包转发一份副本给镜像端口。大多数时候还是得根据情况来,没法在交换机上抓的话就要设法在设备连接交换机的网口抓。
3.4、路由器
路由器上的抓包和交换机并没有太大的不同,主要是关注一点,从路由器开始,网络设备已经对数据包的ip地址产生了影响,而ip地址是我们常关注的信息之一。路由器分为LAN口与WAN口,分别处于两个网段中,内部有一条转发路由为0.0.0.0->WAN IP。
3.5、加密机
通常来说,一个数据包经过加密机加密再经过解密机解密后,该数据包数据链路层之上的部分不会发生变化。经过加密的包有没有抓取分析的价值,一般来说这要由具体的加密方式来决定,例如IPSEC对数据进行加密后,会重新封装新的IP首部;SSL进行加密后,自传输层之下的部分都不会发生改变。具体如何,需要根据自己需要了解的信息进行分析判断。
3.6、防火墙
一般来说,抓包涉及防火墙,都是怀疑某些数据包被防火墙给挡掉了。抓包一般也都是进入防火墙之前抓一次,通过防火墙之后抓一次,对比这两个数据包来判断哪些包被防火墙过滤掉了,以此来判断是不是需要防火墙增开端口或者服务。
常被防火墙给过滤的有:来源或目的ip是未开放ip的数据包;来源或目的端口是未开放端口的数据包;含有某些未开放的协议的数据包;和某些未开放服务有关的数据包。
在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)
专栏1:(该精品技术专栏的订阅量已达到530多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)
C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931
本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!
考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!
专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!
专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达170多个,专栏文章已经更新到460多篇,持续更新中...)
C/C++实战进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html
以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。
专栏3:
C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795
常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!
专栏4:
VC++常用功能开发汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/124272585
将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。
专栏5:
C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.html
根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。
4、Wireshark简要介绍
日常工作中,我们使用Wireshark来查看并分析网络数据包,我们来看Wireshark软件界面的构成。
以新版的Wireshark为例,启动起来后如下所示:
会显示很多网卡,我们要选择在哪个网卡上抓包。在系统安装一些软件时会自动给系统安装一些虚拟网卡,比如安装VMware虚拟机软件时、安装VPN软件时等。 我们应该选择PC上正在使用的物理网卡,可以到系统的适配器页面查看,看看当前PC用的是哪个物理网卡:
从图中可以看出,列表中有两个VMware虚拟机网卡,当前PC的物理网卡的名称应该为“以太网” 。然后双击选择该网卡,就开始抓包了。
再来看一下Wireshark中的窗口构成,如下:
从图中的标记可以看出,主要分以下几块:
1)Display Filter(显示过滤器):用于设置过滤条件;
2)Packet List Pane(封包列表):显示捕获到的封包, 有源地址和目标地址,端口号。 颜色不同,代表
3)Packet Details Pane(封包详细信息): 显示封包中的详细字段信息
4)Dissector Pane(16进制数据):显示包中携带的数据
5)Miscellanous(地址栏,杂项):其他信息
5、Wireshark过滤条件说明
我们在抓包分析软件问题时,一般需要使用IP和端口等过滤条件,事先将与软件当前问题相关的数据包过滤出来(踢除不相关的数据包),然后再进行分析。我们来看看日常使用哪些过滤条件对数据包进行过滤。
可以使用ip地址进行过滤,如下:
ip.dst == 172.16.72.110:目标地址为172.16.72.110
ip.src == 172.16.72.110:源地址为172.16.72.110
ip.addr == 172.16.72.110:源地址或目标地址为172.16.72.110
也可以使用端口进行过滤,如下:
tcp.port == 80:tcp端口为80
udp.port == 1700:udp端口1700
tcp.srcport == 80:tcp源端口为80
tcp.dstport == 80:tcp目标端口为80
也可以将ip和端口组合起来过滤,比如:
ip.addr == 172.16.72.110 && tcp.port == 9002:
tcp.port==443 &&ip.addr==172.16.72.110 &&tcp.flags.syn==1,tcp.flags.syn==1表示是三次握手的SYN包请求
还可以使用具体的协议名过滤,比如tcp、udp、http、websocket、sip、h225、h245、xmpp等,甚至还可以过滤协议中携带的数据内容:
tcp contains "0a89672f-1ffd-45bb-a205-f50649f8fa61"(http请求中携带的参数)
xmpp contains "123456789"(xml中包含字符串)
6、结合常用协议进行分析
6.1、IPv4协议
IPv4是我们最常用的协议之一,因为网络上的设备多以ip地址进行标识,因此我们可以藉由ip地址来初步过滤数据包。同时,复杂的网络环境中大多为基于网络层的设备(比如三层交换机和路由器),因此也可以通过多次抓包以及对IPv4协议的分析来确定网络环境对数据包的影响。
6.2、TCP协议
TCP协议是一种可靠的连接协议,与TCP有关的一般有以下几处:端口号,三次握手,六个标志位,滑动窗口协议。
6.2.1、端口号
作为传输层协议,采用端口号来唯一标识一条连接。
由端口来过滤的条件一般可写为tcp.srcport (tcp连接源端口)、tcp.dstport(tcp连接目的端口)、udp.srcport (udp连接源端口)、udp.dstport (udp连接目的端口)、tcp.port (tcp连接中含有端口)、Udp.port (udp连接中含有端口),条件之间可以使用&&、||、!逻辑运算符连接。
6.2.2、三次握手过程
从下图可以看到wireshark捕获到的TCP包中的每个字段:
TCP三次握手的流程如下所示:
我们通过网络抓包能看到完整的流程:
关于TCP三次握手的详细讲解,可以直接去查看这篇文章,此处就不再赘述了:
TCP三次握手及四次挥手详细图解https://blog.csdn.net/chenlycly/article/details/51657413
6.2.3、TCP报文格式与字段
下面是TCP报文格式图:
上图中有几个字段需要重点介绍下:
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(a)不要将确认序号Ack与标志位中的ACK搞混了。
(b)确认方Ack=发起方Req+1,两端配对。
6.2.4、滑动窗口协议
滑动窗口协议的内容和机制这里不再细说,窗口导致的问题非常少,某些情形下可能因为窗口大小的缘故导致连接被挂起。
6.3、HTTP协议
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是一个属于应用层的面向对象的协议,关于HTTP协议,我们只需要掌握以下几点:URL、Request、Response、状态码、cookie。
除了正常的B/S架构的应用以外,ONVIF协议与RTSP的协议也是建立在HTTP协议的基础上的。
6.3.1、URL
URL,全称是UniformResourceLocator,中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。
URL的格式为:scheme://host:port/path,比如 http://172.16.72.110:9800/pic/20231020.jpg
6.3.2、Requset
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,如下:
6.3.3、Response
服务器接收到一个客户端请求后会回复一个响应消息。HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文,如下:
6.3.4、状态码
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
6.3.5、Cookie
Cookie,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。一般用于给服务器提供与本地客户端相关的信息,比如实现记住密码,自动登录等功能。不安全的cookie会存储用户名和密码等敏感信息,安全的cookie一般是存储sessionID与UTC时间。
6.4、RTP协议
实时传送协议(Real-time Transport Protocol或简写RTP,也可以写成RTTP)是一个网络传输协议,RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTCP协议或者RTSP协议)。
广义的RTP协议分为RTP协议与RTCP协议,RTP使用偶数端口,该条的RTP连接对应的RTCP连接就是使用接下来的奇数端口。在我们公司的产品中,RTCP常常用来实现丢包重传功能。
6.4.1、按照RTP协议解析
一般Wireshark并不会直接将UDP码流解析为RTP的协议,需要自己来设置解析的方式。方法为:找到要解析的UDP码流->右键选择DECODE As或者解码为->在右侧找到RTP协议->apply或者应用,如下所示:
6.5、H264编码格式
H.264,是现阶段比较流行的一种压缩编码方式。在这里不讲原理,只讲如何对H264的码流进行分析。主要有以下几点:如何查看h264码流、帧结束的标识、如何筛选关键帧、分辨率等编码参数如何查看,帧率如何查看。
6.5.1、如何按照H264解析
首先,要将UDP流解析为RTP流,并查看对应的载荷号:
然后在Wireshark主界面上方的菜单栏,点击Edit->Preferences,在打开的窗体中的左侧列表中找到Protocols:
然后在Protocols下方找到H264节点,并在载荷中填入对应载荷号:
然后点击Apply,这样就可以将码流以H264的方式来解析了。
6.5.2、如何筛选关键帧?
先按照端口过滤该RTP流,例如udp.srcport == 60050,然后将过滤出的数据包按照长度由小到大排序(关键帧的起始位一定是小包),找到结尾标识着Sequence parameter set的数据包,这就是关键帧的起始分片。
在下方的数据信息中找到Sequence parameter set字段,查看它对应的16进制字段(假如这里是27)。在过滤中添加&ð[54]==27,就可以找出所有的关键帧起始分片。
6.5.3、如何查看分辨率等编码信息?
在关键帧中可以查找到关于分辨率的信息,如图所示,该数字加1再乘以16即为所得值,即:
(119+1)*16=1920
(33+1)*16=544
可知该分辨率为1080i(1080i为隔行扫描,竖向像素会少一半)。
6.5.4、帧率计算
帧结束的标识:
帧率的计算方法:
1)过滤条件加上rtp.marker==1
2)电话->RTP->流分析:3)RTP Packets /Duration = 帧率
截图中的帧率:4293 / 85.82 = 50fps。
6.5.5、码率计算
先根据端口过滤出码流,然后在在Wireshark主界面上方的菜单栏中点击 统计->捕获文件属性(summary),如下:
平均字节/秒 除以1024即为码率,图中的码率为:409 / 1024 = 0.4MB/S。
标签:协议,一站式,端口,网络,C++,专栏,数据包,抓包,Wireshark From: https://blog.csdn.net/chenlycly/article/details/143025613