QT应用编程: 开发TCP网络调试助手

简介: QT应用编程: 开发TCP网络调试助手

一、环境介绍

操作系统: win10 64位


QT版本:  QT5.12.6


编译器:  MinGW 32


TCP网络调试助手,在网络相关开发、嵌入式开发里使用较多,主要用来测试网络传输,调试等等。


这个版本设计的比较早,没有加入多线程处理连接上来的客户端,一般的调试场景已经满足。对于基本的QT网络开发入门学习借鉴已经足够了。


软件下载:  https://download.csdn.net/download/xiaolong1126626497/17044958


工程完整源代码下载:  https://download.csdn.net/download/xiaolong1126626497/17058921


二、效果图

image.png

三、源代码

3.1 widget.cpp

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/image/14g.png")); //设置图标
    SetStyle(":/qss/blue.css"); //设置样式表
    setWindowTitle("TCP网络调试助手_v2.2 2020年7月11日");
    comboBox_config();
    timer = new QTimer(this); //创建定时器
    connect(timer, SIGNAL(timeout()), this, SLOT(update())); //关联槽函数
    /*控件名字设置*/
    ui->checkBox_ShowTime->setText("接收时间显示");
    ui->checkBox_TxBit->setText("自动发送附加位\\r\\n");
    ui->checkBox_LoopTx->setText("循环发送数据");
    ui->label_4->setText("设置循环间隔ms时间:");
    ui->pushButton_connect->setText("连接");
    ui->pushButton_SendData->setText("发送");
    ui->About->setText("帮助");
    ui->label->setText("1.协议类型");
    ui->label_ip->setText("2.本地IP地址");
    ui->label_prot->setText("3.本地端口");
    ui->label_SendCnt->setText("TX");
    ui->label_RxCnt->setText("RX");
    ui->pushButton_clear->setText("复位");
    ui->plainTextEdit_ShowData->setReadOnly(true);
    ui->pushButton_cleanShow->setText("清除显示");
}
//设置指定样式
void Widget::SetStyle(const QString &qssFile) {
    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) {
        QString qss = QLatin1String(file.readAll());
        qApp->setStyleSheet(qss);
        QString PaletteColor = qss.mid(20, 7);
        qApp->setPalette(QPalette(QColor(PaletteColor)));
        file.close();
    }
}
//基本配置
void Widget::comboBox_config()
{
    /*第一部分:网络设置*/
    //1.1 配置协议
    ui->comboBox_protocol->addItem("TCP Server");
    ui->comboBox_protocol->addItem("TCP Client");
    //1.2. 获取并配置本地IP地址
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int i=0;i<list.count();i++)
    {
        QHostAddress addr=list.at(i);
        if(addr.protocol() == QAbstractSocket::IPv4Protocol)
        {
          ui->comboBox_ipaddress->addItem(addr.toString());
        }
    }
   //1.3 设置可编辑性
    ui->comboBox_ipaddress->setEditable(true);
   //1.4. 设置默认端口号
    ui->lineEdit_prot->setText("8080");
    /*第二部分:发送设置*/
    //2.1设置循环发送时间
    ui->lineEdi_LoopTime->setText("1000");
    //2.2 设置默认发送的内容
    ui->lineEdit_InputTxDtat->setText("https://blog.csdn.net/xiaolong1126626497");
    //接收数量置0
    TxCount=0;
    RxCount=0;
    /*第三部分:选择客户端时用于显示本地端口和IP*/
    ClientShowLocalProtLabel =new QLabel("本地端口:");
    ClientShowLocalIptLabel =new QLabel("本地IP地址:");
    ClientEditProt= new QLineEdit;
    ClientEditIP= new QLineEdit;
    ClientLayout = new QHBoxLayout;
    ClientLayout->addWidget(ClientShowLocalIptLabel);
    ClientLayout->addWidget(ClientEditIP);
    ClientLayout->addWidget(ClientShowLocalProtLabel);
    ClientLayout->addWidget(ClientEditProt);
    /*第四部分:选服务器时用于显示已经连接的客户端*/
    SaverShowLocalProtLabel =new QLabel("已连接的客户端列表:");
    ClientComboBoxList=new QComboBox;
    ClientComboBoxList->setMinimumWidth(180);
    ServerLayout = new QHBoxLayout;
    ServerLayout->addWidget(SaverShowLocalProtLabel);
    ServerLayout->addWidget(ClientComboBoxList);
    ServerLayout->addStretch();
}
Widget::~Widget()
{
    timer->stop(); //停止定时器
    delete timer;
    delete ui;
}
//创建服务器或者连接到服务器
void Widget::on_pushButton_connect_clicked()
{
    if(ui->pushButton_connect->text()=="连接")
    {
        switch(ui->comboBox_protocol->currentIndex())
        {
            case 0: //服务器模式
                NewServer();
                break;
            case 1: //客户端模式
                NewClinet();
                break;
        }
    }else
    {
        switch(ui->comboBox_protocol->currentIndex())
        {
            case 0: //服务器模式
                ui->pushButton_connect->setText("连接");
                for(int i=0;i<TcpFarClientList.count();i++)
                {
                    TcpFarClientList.at(i)->close();
                    TcpFarClientList.removeAt(i);
                }
                LocalTcpServer->close();//关闭服务器
                //取消客户端列表显示
                ui->verticalLayout_9->removeItem(ServerLayout);
                ClientComboBoxList->close();
                SaverShowLocalProtLabel->close();
                //断开服务器之后设置控件可用性
                //创建服务器之后设置控件可用
                ui->comboBox_ipaddress->setEnabled(true);
                ui->comboBox_protocol->setEnabled(true);
                ui->lineEdit_prot->setEnabled(true);
                break;
            case 1: //客户端模式
                LocalTcpClientSocket->close();
                break;
        }
    }
}
//服务器模式:创建服务器
void Widget::NewServer()
{
    /*1. 实例化服务器*/
    LocalTcpServer= new QTcpServer;
    /*2. 设置监听的端口和IP地址*/
    quint16 port=QString(ui->lineEdit_prot->text()).toInt();
    if(ui->comboBox_ipaddress->currentText()=="QHostAddress::Any")
    {
        LocalTcpServer->listen(QHostAddress::Any,port);
    }else
    {
       QHostAddress addr(ui->comboBox_ipaddress->currentText());
       LocalTcpServer->listen(addr,port);
    }
    /*3. 关联连接信号,检测是否有新的客户端连接*/
    connect(LocalTcpServer,SIGNAL(newConnection()),this,SLOT(NewTcpConnection()));
    ui->pushButton_connect->setText("断开连接");
    //添加布局,显示已经连接的客户端列表
    ui->verticalLayout_9->insertLayout(1,ServerLayout);
    ClientComboBoxList->show();
    SaverShowLocalProtLabel->show();
    //创建服务器之后设置控件可用
    ui->comboBox_ipaddress->setEnabled(false);
    ui->comboBox_protocol->setEnabled(false);
    ui->lineEdit_prot->setEnabled(false);
}
//客户端模式:创建客户端
void Widget::NewClinet()
{
    /*1. 创建本地客户端TCP套接字*/
    LocalTcpClientSocket = new QTcpSocket;
    /*2. 设置服务器IP地址*/
    QString Ipaddr=ui->comboBox_ipaddress->currentText();
    QHostAddress FarServerAddr(Ipaddr);
    /*3. 连接客户端的信号槽*/
    connect(LocalTcpClientSocket,SIGNAL(connected()),this,SLOT(LocalTcpClientConnectedSlot()));
    connect(LocalTcpClientSocket,SIGNAL(disconnected()),this,SLOT(LocalTcpClientDisconnectedSlot()));
    connect(LocalTcpClientSocket,SIGNAL(readyRead()),this,SLOT(LocalTcpClientReadDtatSlot()));
    /*4. 尝试连接服务器主机*/
    int prot=ui->lineEdit_prot->text().toInt();
    LocalTcpClientSocket->connectToHost(FarServerAddr,prot);
}
//客户端模式:响应连接上服务器之后的操作
void Widget::LocalTcpClientConnectedSlot()
{
    //显示本地端口和IP
    ClientEditProt->setText(QString::number(LocalTcpClientSocket->localPort()));
    ClientEditIP->setText(LocalTcpClientSocket->localAddress().toString());
    ui->verticalLayout_9->insertLayout(1,ClientLayout);
    ClientEditProt->show();
    ClientEditIP->show();
    ClientShowLocalProtLabel->show();
    ClientShowLocalIptLabel->show();
    //当连接上服务器之后设置控件不可用
    ui->comboBox_ipaddress->setEnabled(false);
    ui->comboBox_protocol->setEnabled(false);
    ui->lineEdit_prot->setEnabled(false);
    ui->pushButton_connect->setText("断开连接");
}
//客户端模式:断开服务器
void Widget::LocalTcpClientDisconnectedSlot()
{
   ui->verticalLayout_9->removeWidget(ClientEditProt);
   ui->verticalLayout_9->removeWidget(ClientEditIP);
   ui->verticalLayout_9->removeWidget(ClientShowLocalProtLabel);
   ui->verticalLayout_9->removeWidget(ClientShowLocalIptLabel);
   ui->verticalLayout_9->removeItem(ClientLayout);
   ClientEditProt->close();
   ClientEditIP->close();
   ClientShowLocalProtLabel->close();
   ClientShowLocalIptLabel->close();
   ui->pushButton_connect->setText("连接");
   //当断开上服务器之后设置控件可用
   ui->comboBox_ipaddress->setEnabled(true);
   ui->comboBox_protocol->setEnabled(true);
   ui->lineEdit_prot->setEnabled(true);
}
//客户端模式:读取服务器发过来的数据
void Widget::LocalTcpClientReadDtatSlot()
{
    //移动滚动条到底部
    QScrollBar *scrollbar = ui->plainTextEdit_ShowData->verticalScrollBar();
    if(scrollbar)
    {
       scrollbar->setSliderPosition(scrollbar->maximum());
    }
    /*判断显示的数据长度是否超出*/
    QString text=ui->plainTextEdit_ShowData->toPlainText();
    if(text.length()>1000) ui->plainTextEdit_ShowData->setPlainText(""); //清空显示
   QByteArray array=LocalTcpClientSocket->readAll();
   //记录接收的字节数并显示
   TxCount+=QString(array).toLocal8Bit().length();
   ui->lcdNumber_RxNumber->display(TxCount);
   text="";
   //判断是否需要显示时间
   if(ui->checkBox_ShowTime->isChecked())
   {
       QDateTime time = QDateTime::currentDateTime();   //获取系统现在的时间
       text+= time.toString("yyyy-MM-dd hh:mm:ss ddd"); //设置显示格式
       text+=" :";
   }
   text+=QString("").fromLocal8Bit(array);
   ui->plainTextEdit_ShowData->appendPlainText(text);
}
void Widget::on_comboBox_protocol_activated(int index)
{
    switch(index)
    {
        case 0: //服务器模式
            ui->label_ip->setText("2.本地IP地址");
            ui->label_prot->setText("3.本地端口号");
            ui->comboBox_ipaddress->clear();
            ui->comboBox_ipaddress->addItem("QHostAddress::Any");
            break;
        case 1: //客户端模式
            ui->label_ip->setText("2.服务器IP地址");
            ui->label_prot->setText("3.服务器端口号");
            ui->comboBox_ipaddress->clear();
            break;
    }
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for(int i=0;i<list.count();i++)
    {
        QHostAddress addr=list.at(i);
        if(addr.protocol() == QAbstractSocket::IPv4Protocol)
        {
          ui->comboBox_ipaddress->addItem(addr.toString());
        }
    }
}
//发送数据
void Widget::on_pushButton_SendData_clicked()
{
    QString text=ui->lineEdit_InputTxDtat->text();
    if(text.isEmpty())
    {
        QMessageBox::warning(this,"发送错误","发送的数据不能为空!",QMessageBox::Ok);
        return;
    }
    if(ui->checkBox_TxBit->isChecked())  //发送附加位
    {
        text+="\r\n";
    }
    QByteArray array=text.toLocal8Bit();
    int count=0;
    switch(ui->comboBox_protocol->currentIndex())
    {
        case 0: //服务器模式
            if(TcpFarClientList.count()<=0)
            {
                timer->stop(); //停止定时器
                ui->checkBox_LoopTx->setChecked(false); //取消循环按钮选择
                QMessageBox::warning(this,"发送错误","没有连接的客户端!",QMessageBox::Ok);
                return;
            }
            for(int i=0;i<TcpFarClientList.count();i++)
            {
                //取出地址列表中的一个客户端地址
                QTcpSocket *item = TcpFarClientList.at(i);
                count=item->write(array);
            }
            TxCount+=count;
            break;
        case 1: //客户端模式
            if(LocalTcpClientSocket->state()==QAbstractSocket::ConnectedState)
            {
                TxCount+=LocalTcpClientSocket->write(array);
            }
            else
            {
                LocalTcpClientSocket->close();
                timer->stop(); //停止定时器
                ui->checkBox_LoopTx->setChecked(false); //取消循环按钮选择
                QMessageBox::warning(this,"发送错误","未连接服务器!",QMessageBox::Ok);
                return;
            }
            break;
    }
    ui->lcdNumber_TxNumber->display(TxCount);
}
//清除计数
void Widget::on_pushButton_clear_clicked()
{
    TxCount=0;
    RxCount=0;
    ui->lcdNumber_RxNumber->display(0);
    ui->lcdNumber_TxNumber->display(0);
}
//服务器模式:响应新连接的客户端
void Widget::NewTcpConnection()
{
    /*创建本地服务器套接字*/
    QTcpSocket *ServerSocket=LocalTcpServer->nextPendingConnection();
    /*关联可读信号*/
    connect(ServerSocket,SIGNAL(readyRead()),this,SLOT(ReadTcpClientData()));
    /*关联断开信号*/
    connect(ServerSocket,SIGNAL(disconnected()),this,SLOT(TcpClientDisconnected()));
    TcpFarClientList.append(ServerSocket);//添加到列表
    //显示已经连接的客户端
    ClientComboBoxList->clear();
    for(int i=0;i<TcpFarClientList.count();i++)
    {
        QString info=TcpFarClientList.at(i)->peerAddress().toString();
        info+=":";
        info+=QString::number(TcpFarClientList.at(i)->peerPort());
        ClientComboBoxList->addItem(info);
    }
}
//服务器模式:响应断开的客户端
void Widget::TcpClientDisconnected()
{
    for(int i=0;i<TcpFarClientList.count();i++)
    {
        //取出地址列表中的一个客户端地址
        QTcpSocket *item = TcpFarClientList.at(i);
        //判断该客户端是否已经断开
        if(item->socketDescriptor()==-1)
        {
            TcpFarClientList.removeAt(i);
        }
    }
    //显示已经连接的客户端
    ClientComboBoxList->clear();
    for(int i=0;i<TcpFarClientList.count();i++)
    {
        QString info=TcpFarClientList.at(i)->peerAddress().toString();
        info+=":";
        info+=QString::number(TcpFarClientList.at(i)->peerPort());
        ClientComboBoxList->addItem(info);
    }
}
//服务器模式:读数据
void Widget::ReadTcpClientData()
{
    /*移动滚动条到底部*/
    QScrollBar *scrollbar = ui->plainTextEdit_ShowData->verticalScrollBar();
    if(scrollbar)
    {
       scrollbar->setSliderPosition(scrollbar->maximum());
    }
    //设置光标到文本末尾
     ui->plainTextEdit_ShowData->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    for(int i=0;i<TcpFarClientList.count();i++)
    {
       if(!TcpFarClientList.at(i)->atEnd())
       {
          QByteArray array=TcpFarClientList.at(i)->readAll();;
          //记录接收的字节数并显示
          RxCount+=QString(array).toLocal8Bit().length();
          ui->lcdNumber_RxNumber->display(RxCount);
          QString text;
          //判断是否需要显示时间
          if(ui->checkBox_ShowTime->isChecked())
          {
              QDateTime time = QDateTime::currentDateTime();   //获取系统现在的时间
              text+= time.toString("【yyyy-MM-dd hh:mm:ss ddd"); //设置显示格式
              text+="】:";
          }
          text+=QString("").fromLocal8Bit(array);
          ui->plainTextEdit_ShowData->appendPlainText(text);
       }
    }
}
//关于
void Widget::on_About_clicked()
{
    QMessageBox::information(this,tr("帮助提示"),"本软件用于TCP网络协议调试!\n"
                                             "暂不支持UDP协议调试!\n"
                                             "如果第一次打开软件字体显示不全\n"
                                             "需要关闭应用第二次打开即可自动适应\n"
                                             "软件作者:DS小龙哥\n"
                                             "BUG反馈:1126626497@qq.com");
}
//是否开始循环发送数据
void Widget::on_checkBox_LoopTx_clicked()
{
    if(ui->checkBox_LoopTx->isChecked()) //是否选择复选框
    {
        int cnt=ui->lineEdi_LoopTime->text().toInt();
        if(cnt<=0)
        {
            QMessageBox::warning(this,"错误提示","发送的时间不合法!",QMessageBox::Ok);
            ui->checkBox_LoopTx->setChecked(false);
            return;
        }
        timer->start(cnt);
    }
    else
    {
        timer->stop(); //停止定时器
    }
}
//定时发送
void Widget::update(void)
{
    on_pushButton_SendData_clicked();
}
void Widget::on_pushButton_cleanShow_clicked()
{
    ui->plainTextEdit_ShowData->setPlainText(""); //清除数据
}

3.2  wigdet.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QHostInfo>  //获取计算机网络信息
#include <QUdpSocket>
#include <QtNetwork>
#include <QHostInfo>
#include <QDebug>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
#include <QMessageBox>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QComboBox>
#include <QFile>
#include <QTimer>
#include <QScrollBar>
#include <QScrollBar>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    int TxCount;
    int RxCount;
    //关于客户端模式相关的变量定义
    QTcpServer *TcpServer;
    QTcpSocket *ServerSocket;
    QTcpSocket *LocalTcpClientSocket;
    QLineEdit *ClientEditProt;
    QLineEdit *ClientEditIP;
    QLabel *ClientShowLocalProtLabel;
    QLabel *ClientShowLocalIptLabel;
    QHBoxLayout *ClientLayout;
    void comboBox_config();
    void NewClinet();
    //关于服务器相关的变量定义
    QTcpServer *LocalTcpServer;
    void NewServer();
    QList<QTcpSocket*> TcpFarClientList;
    QLabel *SaverShowLocalProtLabel;
    QComboBox *ClientComboBoxList;
    QHBoxLayout *ServerLayout;
    void SetStyle(const QString &qssFile);
    QTimer *timer;
private slots:
    void on_pushButton_connect_clicked();
    void LocalTcpClientConnectedSlot();
    void LocalTcpClientDisconnectedSlot();
    void LocalTcpClientReadDtatSlot();
    void NewTcpConnection();
    void TcpClientDisconnected();
    void ReadTcpClientData();
    void on_comboBox_protocol_activated(int index);
    void on_pushButton_SendData_clicked();
    void on_pushButton_clear_clicked();
    void on_About_clicked();
    void on_checkBox_LoopTx_clicked();
    void update();
    void on_pushButton_cleanShow_clicked();
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

3.3  UI设计界面

image.png

目录
相关文章
|
8月前
|
机器学习/深度学习 PyTorch TensorFlow
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic,深度学习探索者。深耕TensorFlow与PyTorch,分享框架对比、性能优化与实战经验,助力技术进阶。
|
SQL 分布式计算 Serverless
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
鹰角网络为应对游戏业务高频活动带来的数据潮汐、资源弹性及稳定性需求,采用阿里云 EMR Serverless Spark 替代原有架构。迁移后实现研发效率提升,支持业务快速发展、计算效率提升,增强SLA保障,稳定性提升,降低运维成本,并支撑全球化数据架构部署。
1416 56
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
|
10月前
|
监控 安全 Shell
管道符在渗透测试与网络安全中的全面应用指南
管道符是渗透测试与网络安全中的关键工具,既可用于高效系统管理,也可能被攻击者利用实施命令注入、权限提升、数据外泄等攻击。本文全面解析管道符的基础原理、实战应用与防御策略,涵盖Windows与Linux系统差异、攻击技术示例及检测手段,帮助安全人员掌握其利用方式与防护措施,提升系统安全性。
423 6
|
人工智能 监控 安全
NTP网络子钟的技术架构与行业应用解析
在数字化与智能化时代,时间同步精度至关重要。西安同步电子科技有限公司专注时间频率领域,以“同步天下”品牌提供可靠解决方案。其明星产品SYN6109型NTP网络子钟基于网络时间协议,实现高精度时间同步,广泛应用于考场、医院、智慧场景等领域。公司坚持技术创新,产品通过权威认证,未来将结合5G、物联网等技术推动行业进步,引领精准时间管理新时代。
|
9月前
|
机器学习/深度学习 人工智能 算法
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic带你深入卷积神经网络(CNN)核心技术,从生物启发到数学原理,详解ResNet、注意力机制与模型优化,探索视觉智能的演进之路。
773 11
|
10月前
|
数据采集 存储 数据可视化
Python网络爬虫在环境保护中的应用:污染源监测数据抓取与分析
在环保领域,数据是决策基础,但分散在多个平台,获取困难。Python网络爬虫技术灵活高效,可自动化抓取空气质量、水质、污染源等数据,实现多平台整合、实时更新、结构化存储与异常预警。本文详解爬虫实战应用,涵盖技术选型、代码实现、反爬策略与数据分析,助力环保数据高效利用。
518 0
|
10月前
|
安全 Linux
利用Libevent在CentOS 7上打造异步网络应用
总结以上步骤,您可以在CentOS 7系统上,使用Libevent有效地构建和运行异步网络应用。通过采取正确的架构和代码设计策略,能保证网络应用的高效性和稳定性。
251 0
|
机器学习/深度学习 算法 测试技术
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
本文探讨了基于图的重排序方法在信息检索领域的应用与前景。传统两阶段检索架构中,初始检索速度快但结果可能含噪声,重排序阶段通过强大语言模型提升精度,但仍面临复杂需求挑战
466 0
图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析
|
12月前
|
监控 安全 Linux
AWK在网络安全中的高效应用:从日志分析到威胁狩猎
本文深入探讨AWK在网络安全中的高效应用,涵盖日志分析、威胁狩猎及应急响应等场景。通过实战技巧,助力安全工程师将日志分析效率提升3倍以上,构建轻量级监控方案。文章详解AWK核心语法与网络安全专用技巧,如时间范围分析、多条件过滤和数据脱敏,并提供性能优化与工具集成方案。掌握AWK,让安全工作事半功倍!
451 0
|
人工智能 安全 网络安全
网络安全厂商F5推出AI Gateway,化解大模型应用风险
网络安全厂商F5推出AI Gateway,化解大模型应用风险
377 0

推荐镜像

更多
  • qt