网络延时测量程序
项目简介
网络延时测量程序
项目需求:
1.客户端与服务端能够通信,并能测量网络延时(客户端发送信息给服务端,服务端收到后立刻回复,客户端收到后计算网络延时)
2.多次测量(10次)
3.在不同场景下进行测试(CPU占用率极高、下载进程占据带宽、内网外网环境)
4.能够读写日志文件,并处理数据
5.图形化界面
关于项目
首先放出项目的代码:Github
这个项目总体来说并不难,思路也是非常简单的。老师建议我们用C语言来写,可以方便我们理解底层通信技术。但是如果我们想完整的实现所有的功能的话,图形化界面肯定就需要使用MFC来做了。同时我们队伍中没有人会MFC,而这个项目又只有一个星期的时间去做完,所以我们队伍决定其他两个人用C语言来写这个项目,利用命令窗口实现功能;我则利用Qt来写一个图形化界面并实现所有的功能。
之所以利用Qt来写,是因为Qt非常简洁、网络的库QTcpsocket也非常好用,而且也比较适合目前的开发环境,MFC这东西我感觉很繁杂、已经很落伍了(只是个人意见....)。所以我果断使用Qt进行开发。而最后实现的功能有以下:
项目环境QtXlsxWriter搭建
安装步骤
Qt的安装直接略过。这里稍微提及一下利用Qt操作Excel的方法:我利用的是QtXlsxWriter。配置方法如下:
首先下载QtXlsxWriter
然后下载activeperl
1.将下载的文件以文件夹的形式都放在Qt的安装目录下
2.然后安装activeperl,安装目录要和Qt在一个磁盘里,否则会不成功;同时在安装时注意将activeperl的安装目录配置到系统环境变量中,如果安装过成勾选了就不用管了。
3.进入Qt 5.9.2 for Desktop
4.输入命令:
cd [QtXlsxWriter所在的目录]
qmake
mingw32-make
mingw32-make install
错误处理
若编译过程中未出现错误提示,表明编译成功;但是如果出现
xlsxzipreader.cpp: In member function ‘void QXlsx::ZipReader::init()’:
xlsxzipreader.cpp:51:66: error: conversion from ‘QVector<QZipReader::FileInfo>’ to non-scalar type ‘QList<QZipReader::FileInfo>’ requested
QList<QZipReader::FileInfo> allFiles = m_reader->fileInfoList();
这样的错误,则是需要进入相应的程序QZipReader::init()中, 添加头文件#include <QVector>
然后把出错的地方的"QList" 用"QVector" 替换掉重新构建就可以了。
测试一下
新建Qt项目,在.pro文件中添加 QT +=xlsx,然后输入
#include <QtXlsx>
QXlsx::Document xlsx("book1.xlsx");//创建表格
/* 设置单元格样式 */
QXlsx::Format format1;
format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);//横向居中
format1.setVerticalAlignment(QXlsx::Format::AlignVCenter);//竖直居中
format1.setFontBold(true);//设置加粗
format1.setFontSize(15); //设置字体大小
format1.setFontColor(Qt::red);//字体颜色
xlsx.mergeCells("B1:C1"); //合并单元格
xlsx.write(1, 2, "检测项目", format1);//在第一行第二列写入内容
xlsx.saveAs("book1.xlsx");//保存
在build文件中查看生成的book1.xlsx,如果有"检测项目"四个大字就说明QtXlsxWriter已经安装成功了。安装教程参照了这篇博客
项目原理
通信模块
首先是网络通信,由于Qt和正常的C语言编程思路不太通,Qt是事件触发型的,即如果检测到buffer里有数据,会发送相应的信号,再由之前程序里写的connect执行槽函数。
延时测量模块
测量延时,我是利用客户端首先获取本地时间,再发送数据(任何都行,但实际上字符串越长对延时也会稍微的有些影响),服务端接收后立刻原封不动的返回这个数据,客户端接收到后再获取本地时间2,利用本地时间2-本地时间
就获得了网络延时。
多次发送模块
单次发送非常好理解,就是点击发送
这个事件触发了发送数据
事件,而发送数据
事件同时在服务端接收到数据后触发了回复
事件,客户端收到服务端发送数据
事件后触发了其他客户端相应的事件(这里没有说相应的事件是因为这里写的事件有些多,包括读取数据、生成execel等等)。多次发送我们或许以为会很简单,直接写个循环多次执行单次发送这个事件不就行了?我也是这样想的,但是事实告诉我们这样是不行的!!。为什么呢?是因为Qt这个socket很奇怪,如果执行循环反复发送这个事件的话,它是会等待后面的数据一起进来然后一起发送、或者是没有规律的时不时发送成功时不时等待后面的,意思就是不能单次发送我们想要的单次数据。刚开始我认为是服务端的buffer没有清理干净的原因,后来查阅相关资料发现是qt中必须增加socket->waitForBytesWritten();
这一行才能表示单次数据直接发送,不必等待后面的数据;加了后就可以多次发送了!!小注意点是在由时间稍微处理一下,具体请看代码吧:
qDebug()<<"循环了10次测试!";
for(int i=0;i<10;i++)
{
QTime startTime = QTime::currentTime();
qDebug()<<startTime;
QTime Nowtime = startTime.addMSecs(3000);
QString str = Nowtime.toString("h:m:s.z");
qDebug()<<str;
socket->write(str.toUtf8());
//socket->flush();
socket->waitForBytesWritten();
socket_Read_Data();
Sleep(3000);
}
图像模块
程序里确实有图像模块的代码,加了qcustomplot的头文件和源文件;本来想实现的功能是点击"图像"这个按钮,会弹出一个包含图表的对话框;然后可以实时的更新测量数据,绘制趋势图。但是经过多次测量,qcustomplot的图像只能显示在mainwindow窗口上,在qdialog的窗口内无法显示;由于时间不够了,这个功能也就启用了;但是这些代码仍然保存着,日后有时间可以找找原因。
生成excel文件
上面已经详细介绍了。这里我只说我的用法,我定义了一个全局变量i,每次执行延时测量程序之后都会自动+1,然后再写入excel中(i,1)单元格;这样就能非常方便的记录所有的数据。
数据分析
由于生成的数据都到excel里了,我们就直接利用excel进行数据处理。在这里我写了excel vba程序,对A列所有的数据进行方差、平均值的计算、并能绘制响应的折线图。实际上也可以用直方图来分析,只是觉得折线图的趋势比较明显,反正都是可以修改的。
最终效果图
测试结果图
CPU占用率到74%的时候的延时
下载文件占用带宽测试
虚拟机测试1
虚拟机测试2
结论
1.外网能直接访问外网
内网不能直接访问另一个内网
同一个内网之间可以互相访问
内网可以访问外网,但外网不能直接访问内网
2.CPU占用率较高的条件下、下载进程占据带宽的时候,网络延时会显著变长
3.不同计算机在同一内网下(校园网)测试的时候会有较长延时,随着距离的增大而变长;可能和转发的路由器数目变多了有关
4.一台计算机自己访问自己,网络延时比较低。
一些思考
由于回应壁程序可以测量带宽,首先抓了个包发现:
是get了4个很大的数据包,根据网络延时和数据包的大小进行带宽测试的。所以如果我们的程序发送指定大小的数据包,并得到平均网络延时就可以测量网络带宽!!
-------------------------------------------
个性签名:一名会音乐、爱健身的不合格程序员
可以Follow博主的Github哦(っ•̀ω•́)っ✎⁾⁾