网络延时测量程序

项目简介

网络延时测量程序
项目需求:
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
04.png
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已经安装成功了。安装教程参照了这篇博客

项目原理

通信模块

tcp02.png
首先是网络通信,由于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列所有的数据进行方差、平均值的计算、并能绘制响应的折线图。实际上也可以用直方图来分析,只是觉得折线图的趋势比较明显,反正都是可以修改的。

最终效果图

02.png

03.png

vba.png

测试结果图

CPU占用率到74%的时候的延时
CPU占用率到74%的时候的延时.png
下载文件占用带宽测试
下载文件占用带宽测试.png
虚拟机测试1
虚拟机测试1.png
虚拟机测试2
虚拟机测试2.png

结论

1.外网能直接访问外网
内网不能直接访问另一个内网
同一个内网之间可以互相访问
内网可以访问外网,但外网不能直接访问内网
2.CPU占用率较高的条件下、下载进程占据带宽的时候,网络延时会显著变长
3.不同计算机在同一内网下(校园网)测试的时候会有较长延时,随着距离的增大而变长;可能和转发的路由器数目变多了有关
4.一台计算机自己访问自己,网络延时比较低。

一些思考

由于回应壁程序可以测量带宽,首先抓了个包发现:
抓访问网络的数据包.png
是get了4个很大的数据包,根据网络延时和数据包的大小进行带宽测试的。所以如果我们的程序发送指定大小的数据包,并得到平均网络延时就可以测量网络带宽!!

posted @ 2018-03-28 13:41  MrYun  阅读(6312)  评论(0编辑  收藏  举报