如何检测网络丢包率,网络丢包率的区别,如何检测网络丢包率,网络丢包率的原因
和往常一样,这篇文章的内容并没有收敛,仍然是一篇征文备忘录,而不是文件。人不在的时候很沮丧,本来就不该来,但是周总结总是要的。
说到网络技术,我个人比较关注IP,其次是链路设备,然后是TCP。这可能和我刚接触网络技术时遇到的公司有关。他们是华为3Com和思科,而不是谷歌、雅虎或BAT。
然而,大多数接触过TCP的人可能更关心它,因为这是他们唯一能接触到的网络技术。虽然在侠义中,TCP不属于网络,但它是一个典型的端到端系统,网络只是通过它的一条路径。
以公共交通系统为例。TCP类似于票务和调度系统。它关注的是票能不能卖,能卖多少票,始发站能不能发车,多长时间发一次等等。至于大巴在途中发生了什么,甚至是哪条路,售票系统并不关心。偶尔小概率的,坐在公交总站的阿姨会在路上接到司机的电话,汇报一些突发情况。车坏了,车翻了,她被刺伤了.那我姑姑唯一能做的就是再派一辆车。她无力修车,无力修路,更无力(其实她没有权利。
.
可悲的痛点是,一个承诺质量的端到端系统,运行在一个完全不能保证质量的分组交换网络中!请注意,高速公路也是具有统计复用的分组交换网络。
全网拥堵,随时可能拥堵。如果我们想设计一个好的TCP,我们必须能够动态地适应网络的现状。我们必须能够探知网络的现状,所以我们需要一个工具。
在给出这个工具之前,我们先从Wireshark说起。
1.如何看待Wireshark中的TCP trace graph?用Wireshark打开一个保存TCP流量的pcap文件,点击statistics-“TCP flow graph-time series(TCP trace)”,我们可以看到一个图表,通过这个图表我们可以了解到网络状态的大部分细节:
但是促使我自己写工具的动机是TCP trace是由TCP自己的拥塞控制算法控制的,所以不客观!诚然,如果出现拥堵,拥堵窗口会下降,但下降多少合适呢?这才是拥塞控制算法说了算,而且是黑箱!另外,如果线路中有噪声,会产生误码,根据垃圾拥塞控制算法缩小窗口。从图表上看,你会误以为发生了拥堵。
所以我需要一个更客观的工具,也就是说它对网络状态一无所知,它也不指望知道网络状态。它只是按照自己的参数以固定的速率发送数据,然后我们通过响应就可以检测到网络中发生了什么。
2.基于包守恒的ping -f。写工具之前,先检查一下现成的ping -f是否好用。
自己试试这个工具,你就知道了。不要谈论它。其实它是基于包守恒,也就是接收n个回复,发出n个请求,所以它会根据网络的状态自动调整速度,但是它是在保守状态下计算丢包率的。
比如下面这个序列:1)。发出100个请求,收到100个回复。
2).发出100个请求,收到80个回复,假设此时发生了拥塞和丢包回复。
3).发送80个请求并接收80个回复,假设拥塞立即得到缓解。
4).请问如何快速了解拥堵缓解?
所以我更喜欢发出固定数量的包然后看响应:1)。发出100个请求,收到100个回复。
2).发出100个请求,收到80个回复,假设此时发生了拥塞和丢包回复。
3).发出100个请求,接收100个回复,立即检测到拥塞缓解。
3.我的Python工具在上面的空间中有概述,我给出了不使用Wireshark和ping -f的原因:
不使用Wireshark的理由:完全是TCP实现的行为草图。在垃圾TCP实现中,根本不可能勾画出网络的状态。即使在完美的TCP实现中,它也显示了TCP如何对网络状态的变化做出反应。这些信息根本没有指导意义,我们也很难知道网络中到底发生了什么。总之,不同的TCP实现对于同样的网络质量会给出不同的数据,画出不同的图,而且太复杂了!
不使用ping -f的原因:说白了,ping -f和tcptrace并没有本质上的区别,只是它的“拥塞控制”机制更简单,完全基于包守恒。不要再说了。
我写的这个工具是自己用的,还可以。该工具可以执行以下功能:
1)检测丢包率这个丢包率是一个客观的丢包率,包括噪声和排队造成的丢包。我在ping -f的基础上做了修改,去掉了根据回复的速度反馈机制,因为它可以检测到更详细的形成条件,以及拥塞对丢包的影响。否则,如果使用ping -f,就要通过斜率来观察这种效应,而当拥塞恢复时,检测器无法及时感知。
这里就不贴图了,基本和ping -f f一样。
2).检测RTT波动这个工具最终会生成一个文件,这个文件的截图如下:
根据这张图画一张图,类似于tcptrace:
注意我是用gnuplot画图,不是Python,因为我在Windows上安装Python画图库失败,Linux上也没有X环境.所以本着UNIX组合小工具的原理,我用Python制作和分析数据,然后用gnuplot展示。我的绘图脚本很简单:
3).检测队列的形成不同于ping -f F。我的工具可以生成点星形文件(.表示已收到响应,而“*”表示数据已发送)。从点和星的分布,我们可以更深入地了解探测队列的细节。以下只是一个例子:
动态图形几乎与ping -f相同:
如果您使用ping -f,您必须留意网点的打印和消除.然后突然增加,接着突然减少,说明有队列,队列突然被清空了.但是,没有留下数据的后期分析。我的工具可以输出三种数据。首先,可以无条件输出详细数据。其次,您可以选择是查看动态数据还是静态点星形数据。事实上,通过详细的输出,完全可以生成后两种数据。之所以在程序中直接支持,完全是为了方便。
以红色队列为例,丢包往往是缓慢的、随机的,然后如果不缓解拥塞,丢包会趋于连续,表现为星号越来越连续,点的连续性相反,趋于离散.我的工具不重复,只是观察,所以完全可以通过点和星的分布来分析队列的细节,而且很有可能可以发现路径上是否有UDP流氓!就算你控制不了自己的路,绕不过去,难道你就不能反制吗?你可以通过点和星的分布变化,知道发送方主动降速是否缓解了拥塞。
4.如何使用这个工具。首先,不能盲目探查。您必须首先有一个大致的拓扑结构。比如说是百度。我们想知道百度路径中的情况。利用古老的魔法追踪路线,我们可以获得很多信息:
为什么要用Windows的tracert?因为我的虚拟机是NAT模式,特殊原因不能用Bridge,所以用Windows.
获得路径细节后,我们可以一步一步地探测每个节点,如下所示:/IC . py 183.56.64.62 1 1000 1。/IC . py 14.29.121.206 1 1000 1
.
由于我的程序缺乏时间精度,很难确定更详细的信息,但这个问题可以在10秒内解决.为什么不呢?因为我觉得够了。
5.说到最后,代码呢?前面这么多,代码呢?github中的代码
但这里也有一份副本:
#!/usr/local/bin/python IMPORT sys IMPORT time From time IMPORT sleep,CTIME IMPORT SIGNAL IMPORT Threading From Scapy。ALL IMPORT * #指定目标IP地址target=sys.argv[1]#指定执行次数tot=int(sys.argv[2])#指定数据包数量tot_per=int(sys.argv[3])#指定是否回显VL=int(sys . argv[4])FLT= host target 和ICMP handle=open (/dev/null , w )out _ list=[]in _ list=[]def output():ALL=out _ list in _ list ALL . sort(lambda x,y:_ exit(0)def signal _ handler(signal,frame):output()类thread wrapper(threading。Thread):def __init__(self,func,args,name= ):threading . thread . _ _ init _ _(self)self . name=name self . func=func self . args=args def run(self):apply(self . func,Self.args)#将结果输出到list def print recv(PKT data):if icmp in PKT data和PKT data[icmp]:seq=str(PKT data[icmp]。seq)if seq==tot _ per 2:return if str(PKT data[IP].dst)==target:handle . write( * )handle . flush()out _ list . append(( ,1,seq,time . clock()))else:if VL==2:handle . write( . )else:handle . write( b b )handle . flush()in _ list . append((-,0,seq,Time。Clock ()) #接收到seq 2的包后停止包捕获并终止程序def check Stop(PKT data):if ICMP in PKT data and PKT data[ICMP]:seq=str(PKT data[ICMP].seq) if int (seq)==tot_per 2和str(pktdata[IP]。src)==target:handle . write( N exit: ctime() N )output()返回true返回false #发送线程def send _ packet():times=0 while times TOT:times=1 send(IP(DST=target)/ICMP(seq=(0,tot _ per))/test ,Verbose=0,loop=1,count=1)send(IP(DST=target)/ICMP(SEQ=TOT _ per 2)/ bye ,verbose=0) #接收线程def recv _ packet (): sniff (PRN_ _ name _ _)send _ thread . set daemon(True)send _ thread . start()recv _ thread=thread wrap er(recv_packet,(),recv _ packet。_ _ name _ _)recv _ thread . set daemon(True)recv _ thread . start()signal . pause()if _ _ name _ _= _ _ main _ _ :if VL!=0:handle . close()handle=sys . stderrsignal . signal(signal。SIGINT,signal_handler)启动()
这个代码写的不好,因为我真的不知道怎么编程。
这段代码使用了令人陶醉的scapy!五年前摸过的这个东西,一直用到了今天。关于scapy的文档,我认为这是更好的一个。
最后,本文再举一个例子来说说TCP bat瞎了,TCP瞎了。蝙蝠虽然瞎了,但不会碰壁,靠的是声波定位,而TCP虽然瞎了也能保持流畅传输,靠的是ACK时钟流。这就引出了另一个想法,效果就是我们可以采取一些措施来捕杀蝙蝠。
不像TCP,蝙蝠发出的声波是无法缓存的,一直是直行的。但是,TCP发出的数据包会被中间网络设备缓存很长时间。所以TCP测得的RTT除以2不一定就是数据包到达接收端的时间!如果你不明白我的意思,请考虑以下场景:0)。从发送端到接收端的路径传输需要10秒,所以不考虑缓存,来回需要20秒;
1)在时间点a,发送数据包p;
2)在到达接收端之前,5秒后,数据包P被路径中间的设备缓存10秒;
3)在时间点A 15秒后,数据包P继续向前移动,再过5秒到达接收端;
4)数据包P的ACK不被接收端缓存,10秒后返回给发送端。
经过计算,在时间点A发送的数据包P的RTT是5 ^ 10 ^ 5 ^ 10=30秒,除以2就是15秒。15秒是发送方到达接收方的时间吗?显然不是!如果TCP不是盲的,那么它一定知道上面的过程。但是TCP是盲的,所以不知道上面的具体流程。如果没有缓存数据包P,显然只需要10秒就可以到达接收端。不过现在算下来是15秒。多出来的5秒钟呢?TCP不知道,所以传统上,TCP会认为有拥塞排队。
但是TCP真的很容易判断拥塞排队的细节吗?
TCP会将RTT的剧增视为拥塞,但是:a .如果在数据包P到达接收端的过程中发生排队,则数据包到达接收端的总时间为20秒,RTT/2=15秒,则TCP少计算5秒;
B.如果排队发生在向发送方返回ACK的过程中,则数据包到达接收方的总时间为10秒,RTT/2=15秒。此时TCP多计算5秒。
B-1。如果ACK拥塞或被丢弃,后面的ACK将共同代替ACK来确认发送的数据。TCP对数据包P和ACK的处理是不同的!
因此,RTT的突然增大(及其高值)很容易识别拥塞的发生,但从RTT的抖动很难区分拥塞的细节,更不用说区分偶然的噪声丢包和拥塞丢包了。
所以回声定位技术给了我一些想法,我其实已经思考了很久。我们可以从流量整形开始,如何找到中间网络设备。
最后,虽然我是个典型的IP迷,但我完全没有贬低TCP的意思。其实我并不经常接触中间网络的设备。我之所以一直鄙视TCP的性能,是因为我一直发现很多所谓的“精通网络编程”的人,其实是“精通编程”,但根本不懂网络。另一个极端是我在2013-2014年遇到的一些CCIE,他们真的精通网络。说实话,我鄙视玩网络设备却不懂编程的人,鄙视在端主机编程却不懂网络编程的人。但其实我更鄙视自己。
TCUMP/Wireshark/Tshark数据包捕获工具是一款利器,但绝对不是唯一的。其实遇到问题只靠分析包的人,可能长期从事协议分析和逆向工作,在这段时间里形成了自己的工作方式。如果他是路由器和交换机工作人员,他可能会依赖另一种工具。这就是网络复杂性的体现。
如果我遇到那些曾经不喜欢HSRP、BGP、PolicyRouting、SpanningTree、Teaming等日常事务的CCIE人。同时对程序员来来往往的套接字、TCP、公告窗口、数据包捕获等有问题。只能说明一个问题。我是个婊子和白痴。