Android IOS WebRTC 音视频开发总结(五六)-- 如何测试网络性能?
本文主要介绍如何测试网络性能,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help
网络性能直接决定了视频通话效果,比如qq,很多时候我们我们觉得通话效果不错,但有些时候体验很差,这时候我们怎么判断是网络不好还是产品本身质量问题呢?最好的办法就是有工具能直接测试当前网络质量,这也正是本文的主题,原文最早来自环信音视频专家符宁,由kelly进行整理和编辑。
一、性能指标:
测试网络性能之前我们得先知道衡量网络性能好坏得几个指标:
1、带宽(吞吐量):
1.1、单位时间内传输的数据量,单位通常是每秒比特数,记作bps;
1.2、带宽反映了网络的传输能力,越大越好;
2、丢包
2.1、数据包丢失个数,等于“发送数据包数” - “接受数据包数”;
2.2、丢包反映了网络可靠性,越小越好;
3、时延
3.1、数据包从发送开始到接收到该数据所耗费的时间,单位通常是毫秒;
3.2、时延反映了网络的速度,越小越好;
4、抖动
4.1、指时延的变化,即两个数据包时延的差值;
4.2、抖动反映了网络的稳定性,越小越好;
5、乱序
5.1、指接收到的数据包顺序和发送顺序不一致的次数;
5.2、乱序反映了网络的稳定性,越小越好;
5.3、当乱序比较严重时,丢包也会比较严重,所以一般都以丢包指标为主,忽略乱序指标;
二、测试方法
方法一:ping
ping是最常见的,几乎在所有的OS上都有它的存在。 其工作原理如图:
- Local发送的数据包,Remote收到数据包后原样发回来;
- 数据包里包含有序号和时间戳信息;
- 序号用于判断是否丢包;
- 时间戳用于计算来回时延(图中蓝色部分),它等于接收时间减去数据包时间戳;
不同OS的ping命令选项可能会略有差别,以Mac OSX的ping为例:
1 $ping -s 1024 192.168.1.100
2
3 PING www.microsoft.com (23.42.217.205): 1024 data bytes
4
5 1032 bytes from 23.42.217.205: icmp_seq=0 ttl=49 time=83.883 ms
6
7 1032 bytes from 23.42.217.205: icmp_seq=1 ttl=49 time=77.958 ms
8
9 1032 bytes from 23.42.217.205: icmp_seq=2 ttl=49 time=80.053 ms
10
11 1032 bytes from 23.42.217.205: icmp_seq=3 ttl=49 time=78.244 ms
12
13 1032 bytes from 23.42.217.205: icmp_seq=4 ttl=49 time=77.937 ms
14
15 ...
16
17 --- 192.168.1.100 ping statistics ---
18
19 30 packets transmitted, 29 packets received, 3.3% packet loss
20
21 round-trip min/avg/max/stddev = 77.843/95.375/141.314/19.167 ms
其中 -s 1024 指示包的大小为1024字节;从ping结果可以看出,发送了30个包,收到29个包,3.3%的丢包率,最小时延77.843毫秒,最大时延141.314毫秒,平均时延95.375毫秒,时延的标准差19.167。另外,ping用的是ICMP协议,网络对ICMP协议处理性能,可能跟UDP或TCP是不一样的,所以测试结果只能做为参考。
小结:ping的优点是简单便捷,可以测试时延和丢包,缺点是无法测试带宽。
方法二:iperf
iperf功能功能强一些,可以测带宽,丢包,抖动, 但是测不了时延。它的工作原理如图:
从图中可以看出iperf是单向发数据包,并不会像ping一样接收方把数据包发回给发送方,所以它是测不了时延,但能测试抖动。
抖动等于接收时间间隔(绿色长度)减去发送时间间隔(蓝色长度,即timestamp2-timestamp1)。
下面是一个例子。
服务端:
1 $iperf -u -s -p 12345 -i 1 -w 1000000
2 ------------------------------------------------------------
3
4 Server listening on UDP port 12345
5
6 Receiving 1470 byte datagrams
7
8 UDP buffer size: 977 KByte
9
10 ------------------------------------------------------------
客户端:
1 $ iperf -u -c 127.0.0.1 -p 12345 -i 1 -t 5 -b 16K -l 62
2
3 ------------------------------------------------------------
4
5 Client connecting to 127.0.0.1, UDP port 12345
6
7 Sending 62 byte datagrams
8
9 UDP buffer size: 9.00 KByte (default)
10
11 ------------------------------------------------------------
12
13 [ 4] local 127.0.0.1 port 59805 connected with 127.0.0.1 port 12345
14
15 [ ID] Interval Transfer Bandwidth
16
17 [ 4] 0.0- 1.0 sec 2.00 KBytes 16.4 Kbits/sec
18
19 [ 4] 1.0- 2.0 sec 1.94 KBytes 15.9 Kbits/sec
20
21 [ 4] 2.0- 3.0 sec 1.94 KBytes 15.9 Kbits/sec
22
23 [ 4] 3.0- 4.0 sec 1.94 KBytes 15.9 Kbits/sec
24
25 [ 4] 4.0- 5.0 sec 2.00 KBytes 16.4 Kbits/sec
26
27 [ 4] 0.0- 5.1 sec 9.87 KBytes 16.0 Kbits/sec
28
29 [ 4] Sent 163 datagrams
30
31 [ 4] Server Report:
32
33 [ 4] 0.0- 5.1 sec 9.87 KBytes 16.0 Kbits/sec 0.046 ms 0/ 163 (0%)
其中 -b 16K 指定了带宽参数。测试结果为丢包0个,平均抖动为0.046毫秒。
方式三:自己开发
1 or(unsigned second = 0; second < test_seconds; second++)
2
3 {
4
5 for(unsigned ui = 0; ui < 8; ui++)
6
7 {
8
9 sendto 1024 bytes;
10
11 }
12
13 msleep(1000);
14
15 }
从上面可以看出,ping和iperf各有优缺点,通常需要两者组合才能满足我们的需求。
有时候现有工具不能满足实际应用的需求,比如说完全模拟实际业务环境或者在产品里集成测试功能,这时候就需要自己造轮子。
我们这里只讨论造轮子得关键点之一:如何匀速发送数据?
我们以设定发送包长为1024字节,带宽为64kbps为例子,讨论发送数据的实现方案。
发送数据最简单的方法就是,起一个线程,每秒直接发送完当前秒的数据,然后sleep一秒,再继续发送,如下:
这种方法比较简单,但是因为发送数据是需要花费时间的,假如发送64Kbit花费了5毫秒,实际发送码率(带宽)为64/1005≈63.68Kbps,比设定值低一些。
把发送时间考虑在内,第2个改进后的代码版本如下:
1 for(unsigned second = 0; second < test_seconds; second++)
2
3 {
4
5 unsigned ts_start = gettimestamp();
6
7 for(unsigned ui = 0; ui < 8; ui++)
8
9 {
10
11 sendto 1024 bytes;
12
13 }
14
15 unsigned elapsed = gettimestamp() - ts_start;
16
17 msleep(1000-elapsed);
18
19 }
从大尺度上看,这个版本确实会按设定带宽发送数据,但从小的的时间片上看,其瞬时发送速率是非常高的。
假如发送64Kbit花费了5毫秒,则瞬时速率为 64*1000/5=12800Kbps,是设定值的20倍。
这种瞬时高发送速率可能会导致网络中某些路由器或交换机来不及处理而大量丢包,所以我们继续改进:
“在每发送一个包时check是否发送太快,如果发送太快的话就sleep一下缓一缓”。
改进后的第三个版本如下:
1 uint64_t sent_bytes = 0;
2
3 unsigned kick_time = gettimestamp();
4
5 for(unsigned second = 0; second < test_seconds; second++)
6 {
7 sendto 1024 bytes;
8 sent_bytes += 1024;
9 unsigned elapsed = gettimestamp() - kick_time;
10 unsigned normal = sent_bytes * 1000 * 8 / (64*1000);
11
12 if(normal > elapsed)
13 {
14 msleep(normal-elapsed);
15 }
16 }
这个版本基本能够按照设定值匀速发送数据了。
当然,它还不是最完美的,当设定带宽很高而包长很小时,会导致太多的check,占用太多CPU。这里就不继续改进了,有兴趣的看官可以自己实现之。
原文地址:http://blog.easemob.com/?p=308
Android IOS WebRTC 音视频开发总结(五六)-- 如何测试网络性能?的更多相关文章
- Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验
前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...
- Android IOS WebRTC 音视频开发总结(六五)-- 给韩国电信巨头做咨询
本文主要总结咨询过程中的一些问题,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam 韩国电信巨头sk想了解国内移动互联网rtc现状,所以上周请我过去给他们的相关人员 ...
- Android IOS WebRTC 音视频开发总结(六十)-- 您为什么招不到适合的音视频人才
本文主要介绍音视频行业招聘现状,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com 有过音视频人才招聘经验的应该都深有 ...
- Android IOS WebRTC 音视频开发总结(六四)-- webrtc能走多远我不知道,但这个市场真实存在
本文主要总结目前都有哪些使用场景用到webrtc,文章最早发表在我们的微信公众号上,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com webrtc只 ...
- Android IOS WebRTC 音视频开发总结(六二)-- 大数据解密国外实时通讯行业开发现状
本文主要介绍国外实时通讯行业现状,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com 上篇文章我们采用百度搜索指数来分 ...
- Android IOS WebRTC 音视频开发总结(六三)-- 2016国内IM云服务行业分析
本文主要国内IM云服务行业分析,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com 谈到IM我们最先想到的是qq和微信 ...
- Android IOS WebRTC 音视频开发总结(六九)-- qq视频通话都是p2p,我们还怕啥?
本文主要介绍在线教育这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help 先简单介绍什么是p2p? p是peer ...
- Android IOS WebRTC 音视频开发总结(六八)-- Google: What's next for WebRTC
本文主要从用户,公司和技术角度分析美女视频直播这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help Justio ...
- Android IOS WebRTC 音视频开发总结(六七)-- 在线教育虽火要做好其实不容易
本文主要介绍在线教育这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help 最近很多朋友在咨询在线教育的事(其实之 ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
随机推荐
- JavaScript笔记之数组 keyword(存储和释放&堆栈 & 按值 引用)
1.数组创建及初始化 var obj=new Array(); var arr=[]; 可以延伸为长度一定的,字面量定义数组 2.堆栈 按值传递 引用类型 数组是引用类型,不是值传递, 栈:系桶自动分 ...
- mat(Eclipse Memory Analyzer tool)之二--heap dump分析
文章中的shallow.retained关键字的说明见:GC是如何回收时的判断依据.shallow size.retained size 在本文中,将介绍MAT(Eclipse Memory Anal ...
- python的装饰器
什么是python的装饰器? 网络上的定义: 装饰器就是一函数,用来包装函数的函数,用来修饰原函数,将其重新赋值给原来的标识符,并永久的丧失原函数的引用. 在google上搜索下python 装饰器 ...
- MySQL作业
创建作业事件 MONTH STARTS '2015-01-01 05:30:01' ON COMPLETION NOT PRESERVE ENABLE DO CALL sp_moveLoginReco ...
- quartz定时任务时间设置描述
这些星号由左到右按顺序代表 : * * * * * * * 格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , ...
- position中多次用到了relative和absolute,能不能具体介绍一下这两者的区别?
position中多次用到了relative和absolute,能不能具体介绍一下这两者的区别? 一个是相对定位,一个是绝对定位. absolute生成绝对定位的元素,相对于 static 定位以外的 ...
- centos 6.5 安装 buildbot-slave 0.8.9
公司服务器多数都用的centos,这个是大环境,改不了,只好研究怎么安装buildbot-slave. buildbot-master倒是没有问题,可控,自己弄了一个ubuntu14来玩. cento ...
- [SQL]patindex的用法
返回指定表达式中某模式第一次出现的起始位置:如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零. Transact-SQL 语法约定 语法 PATINDEX ( '%pattern%' , ...
- 使用spark访问elasticsearch的数据
使用spark访问elasticsearch的数据,前提是spark能访问hive,hive能访问es http://blog.csdn.net/ggz631047367/article/detail ...
- 安装 Python
Python安装.配置图文详解 一. Python简介: Python在Linux.windows.Mac os等操作系统下都有相应的版本,不管在什么操作系统下,它都能够正常工作.除非使用平台相关功能 ...