Qt/C++开源项目 TCP客户端调试助手(源码分享+发布链接下载)

这是一个TCP客户端调试助手,具有简洁直观的界面,用户能够方便地测试TCP协议的通信功能,并可同时作为客户端与服务器端使用。以下是该程序的功能特点及用途介绍:

功能特点:

  1. TCP客户端与服务器调试:支持同时作为TCP客户端和服务器端使用,方便进行本地和远程通信的调试。
  2. 连接状态监控:实时显示客户端和服务器的连接状态,帮助用户快速了解连接是否成功。
  3. 发送与接收数据:支持手动输入数据进行发送,能够清晰显示发送和接收的数据,帮助用户观察通信效果。
  4. 自动定时发送:具有自动发送功能,用户可以根据需要设置自动发送的时间间隔,用于测试持续发送的情况。
  5. HEX显示模式:提供十六进制模式显示发送和接收的数据,方便用户调试协议中的字节流。
  6. 多条定时发送指令:可预设多条指令进行定时发送,适合需要同时发送多组数据的场景。
  7. 清空缓存功能:提供一键清空接收缓存和发送缓存的功能,确保数据流的清晰可见性。
  8. 提示信息展示:通过不同颜色的提示信息,提醒用户连接状态、发送接收成功或失败等,便于迅速做出判断。

用途:

  • 网络通信调试:用于调试TCP/IP协议下的网络通信,适合网络设备开发、网络应用开发人员使用。
  • 协议验证:能够帮助验证通信协议的正确性,尤其是需要手动发送测试指令的场景。
  • 服务器负载测试:通过设置多条自动发送指令,可以用于初步测试服务器的负载能力。
  • 学习和测试工具:对网络编程和通信协议学习者来说,是一个很好的入门工具,可以直观地理解TCP通信机制。

下载链接:

通过百度网盘分享的文件:TCP调试助手.zip
链接:https://pan.baidu.com/s/1ItOuy6e8XgN1jw7lt-WYwA?pwd=cedu 
提取码:cedu

源码分享

#ifndef TCPCLIENTTHREAD_H
#define TCPCLIENTTHREAD_H#include <QThread>
#include <QTcpSocket>
#include <QMutex>
#include <QQueue>#define tc(a) QString::fromLocal8Bit(a)class TcpClientThread : public QThread
{Q_OBJECTpublic:explicit TcpClientThread(QObject *parent = nullptr);~TcpClientThread();void setServerInfo(const QString &host, int port);  // 设置服务器地址和端口void sendData(const QByteArray &data);              // 发送数据void stop();                                        // 停止线程signals:void clientConnected();     // 客户端连接信号void clientDisconnected();  // 断开连接信号void errors(int index, const QString &msg);         // 错误信号void warnings(int index, const QString &msg);       // 警告信号void informations(int index, const QString &msg);   // 信息信号void ClientInfor(const int flag, const QByteArray &msg); // 接收到的信息信号protected:void run() override;  // 重写线程的 run() 函数private slots:void onReadyRead();      // 处理数据读取void onDisconnected();   // 处理断开连接private:QTcpSocket *tcpSocket;   // TCP 套接字QString host;            // 服务器地址int port;                // 服务器端口QMutex mutex;            // 互斥锁,用于保护缓冲区QQueue<QByteArray> sendBuffer; // 发送缓冲队列bool m_run;          // 标志线程是否运行
};#endif // TCPCLIENTTHREAD_H
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QStandardItemModel>
#include "tcpclientthread.h"// 定义宏用于中文字符转换
#define tc(a) QString::fromLocal8Bit(a)QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
enum RunTimeStatus
{Error,            ///< 错误信息Warning,          ///< 警告信息Information,     ///< 常规信息
};
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();void initStyle();//创建发送框void createSendLinEdit();private slots:void onClientConnected(); // 客户端连接信号槽void onClientDisconnected(); // 客户端断开信号槽void handleErrors(int index, const QString &msg);      // 处理错误信号槽void handleWarnings(int index, const QString &msg);    // 处理警告信号槽void handleInformations(int index, const QString &msg); // 处理信息信号槽void handlerClientInfor(const int flag,const QByteArray &data);void writeRunTimeMsgs(const QString &msg, const int level); // 输出运行时消息void on_clearRunTimeutton_clicked();void on_clearRecvButton_clicked();void on_closeTip_clicked();void on_connectedServerButton_clicked();void on_disconectedserverButton_clicked();void on_newOpenClient_clicked();void on_newOpenServer_clicked();private:Ui::MainWindow *ui;TcpClientThread *tcpClientThread;  // TCP 客户端线程
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QTextEdit>
#include <QFile>
#include <QProcess>
#include "timesendwidget.h"
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow),tcpClientThread(new TcpClientThread(this))
{ui->setupUi(this);// 连接 TcpClientThread 的信号到 MainWindow 的槽connect(tcpClientThread, &TcpClientThread::clientConnected, this, &MainWindow::onClientConnected);connect(tcpClientThread, &TcpClientThread::clientDisconnected, this, &MainWindow::onClientDisconnected);connect(tcpClientThread, &TcpClientThread::errors, this, &MainWindow::handleErrors);connect(tcpClientThread, &TcpClientThread::warnings, this, &MainWindow::handleWarnings);connect(tcpClientThread, &TcpClientThread::informations, this, &MainWindow::handleInformations);connect(tcpClientThread, &TcpClientThread::ClientInfor, this, &MainWindow::handlerClientInfor);createSendLinEdit();initStyle();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::initStyle()
{//加载样式表QString qss;QFile file(":/qss/psblack.css");if (file.open(QFile::ReadOnly)) {
#if 1//用QTextStream读取样式文件不用区分文件编码 带bom也行QStringList list;QTextStream in(&file);//in.setCodec("utf-8");while (!in.atEnd()) {QString line;in >> line;list << line;}qss = list.join("\n");
#else//用readAll读取默认支持的是ANSI格式,如果不小心用creator打开编辑过了很可能打不开qss = QLatin1String(file.readAll());
#endifQString paletteColor = qss.mid(20, 7);qApp->setPalette(QPalette(paletteColor));qApp->setStyleSheet(qss);file.close();}}void MainWindow::createSendLinEdit()
{for(int i=0;i<10;i++){TimeSendWidget *sendWidget=new TimeSendWidget;connect(sendWidget,&TimeSendWidget::sendLineData,[=](const QByteArray &data ){if(data.isEmpty()){writeRunTimeMsgs(tc("信息为空,拒绝发送"),Warning);return ;}if(tcpClientThread)tcpClientThread->sendData(data);});ui->verticalLayout->addWidget(sendWidget);}
}// 处理客户端连接的槽函数
void MainWindow::onClientConnected()
{writeRunTimeMsgs(tc("客户端连接成功") , 2);ui->connectedServerButton->setEnabled(false);
}// 处理客户端断开的槽函数
void MainWindow::onClientDisconnected()
{writeRunTimeMsgs(tc("客户端断开连接"), 1);ui->connectedServerButton->setEnabled(true);
}// 处理错误信号
void MainWindow::handleErrors(int index, const QString &msg)
{Q_UNUSED(index);writeRunTimeMsgs(msg, Error);
}// 处理警告信号
void MainWindow::handleWarnings(int index, const QString &msg)
{Q_UNUSED(index);writeRunTimeMsgs( msg, Warning);
}// 处理信息信号
void MainWindow::handleInformations(int index, const QString &msg)
{Q_UNUSED(index);writeRunTimeMsgs(msg, Information);
}void MainWindow::handlerClientInfor(const int flag, const QByteArray &data)
{QString prefix;QString color;QString msg=tc("%1客户端: %3").arg(flag>0?tc("接收←"):tc("发送→")).arg(ui->isShowHexButton->isChecked()? data.toHex(' ').toUpper():QString::fromLocal8Bit(data));if(flag>0){//更新显示信息ui->recvByte->setValue(ui->recvByte->value()+data.size());ui->recvFram->setValue(ui->recvFram->value()+1);if(!ui->isShowRecvButton->isChecked())return;prefix = tc("【接收】");color = "#00ff00";}else{ui->sendByte->setValue(ui->sendByte->value()+data.size());ui->sendFram->setValue(ui->sendFram->value()+1);if(!ui->isShowSendButton->isChecked())return;prefix = tc("【发送】");color = "orange";}// 获取当前时间QString timestamp = ui->isShowTimeButton->isChecked()?QDateTime::currentDateTime().toString("hh:mm:ss(zzz)"):"";// 将消息插入到QTextEdit中并改变颜色// 将消息插入到QTextEdit中并改变颜色QString formattedMsg = QString("<span style='color:%1;'>%2 %3: %4</span>").arg(color, prefix, timestamp,msg);ui->receiveTextEdit->append(formattedMsg);
}// 输出运行时消息
void MainWindow::writeRunTimeMsgs(const QString &msg, const int level)
{QString prefix;QString color;// 获取当前时间QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");switch (level) {case 0: // 异常prefix = tc("【异常】");color = "red";break;case 1: // 警报prefix = tc("【警报】");color = "orange";break;case 2: // 提示prefix = tc("【提示】");color = "#00ff00";break;}// 将消息插入到QTextEdit中并改变颜色QString formattedMsg = QString("<span style='color:%1;'>%2 %3: %4</span>").arg(color, prefix, timestamp, msg);ui->outputTextEdit->append(formattedMsg);}void MainWindow::on_clearRunTimeutton_clicked()
{ui->outputTextEdit->clear();
}void MainWindow::on_clearRecvButton_clicked()
{ui->receiveTextEdit->clear();
}void MainWindow::on_closeTip_clicked()
{ui->groupBox->setVisible(!ui->groupBox->isVisible());
}void MainWindow::on_connectedServerButton_clicked()
{QString host = ui->hostLineEdit->text();int port = ui->portspinBox->text().toInt();if (!tcpClientThread->isRunning()){tcpClientThread->setServerInfo(host, port);tcpClientThread->start();  // 启动线程} else{// QMessageBox::warning(this, tc("警告"), tc("已经连接到服务器"));}
}void MainWindow::on_disconectedserverButton_clicked()
{if(tcpClientThread)tcpClientThread->stop();
}void MainWindow::on_newOpenClient_clicked()
{if (!QProcess::startDetached(QCoreApplication::applicationFilePath())) {writeRunTimeMsgs(tc("新客户端启动失败!"),Error);} else {writeRunTimeMsgs(tc("新客户端启动成功!"),Information);}}void MainWindow::on_newOpenServer_clicked()
{if (!QProcess::startDetached("QTcpServerDemo.exe")) {writeRunTimeMsgs(tc("新服务器启动失败!"),Error);} else {writeRunTimeMsgs(tc("新服务器启动成功!"),Information);}
}
#include "tcpclientthread.h"
#include <QHostAddress>
#include <QEventLoop>#define tc(a) QString::fromLocal8Bit(a)TcpClientThread::TcpClientThread(QObject *parent): QThread(parent), tcpSocket(nullptr), m_run(true)
{
}TcpClientThread::~TcpClientThread()
{stop();  // 停止线程wait();  // 等待线程结束
}void TcpClientThread::setServerInfo(const QString &host, int port)
{this->host = host;this->port = port;
}void TcpClientThread::run()
{tcpSocket = new QTcpSocket();connect(tcpSocket, &QTcpSocket::readyRead, this, &TcpClientThread::onReadyRead);connect(tcpSocket, &QTcpSocket::disconnected, this, &TcpClientThread::onDisconnected);// 连接到服务器tcpSocket->connectToHost(QHostAddress(host), port);if (tcpSocket->waitForConnected(3000)){emit clientConnected();emit informations(0, tc("已成功连接到服务器"));} else {emit errors(0, tc("连接服务器失败"));return;}m_run = true;QEventLoop eventLoop;  // 创建局部事件循环// 主循环,处理事件和发送数据while (m_run) {// 处理事件,防止阻塞信号槽eventLoop.processEvents(QEventLoop::AllEvents, 50);// 检查发送队列QMutexLocker locker(&mutex);if (!sendBuffer.isEmpty()){QByteArray dataToSend = sendBuffer.dequeue();if (tcpSocket->write(dataToSend) == -1){emit errors(1, tc("发送数据失败"));} else{emit ClientInfor(0,dataToSend);}}msleep(10);  // 避免占用过多CPU}// 断开连接if (tcpSocket->state() == QAbstractSocket::ConnectedState) {tcpSocket->disconnectFromHost();if (tcpSocket->state() != QAbstractSocket::UnconnectedState) {tcpSocket->waitForDisconnected(3000);}}tcpSocket->deleteLater();
}void TcpClientThread::stop()
{m_run = false;
}void TcpClientThread::sendData(const QByteArray &data)
{QMutexLocker locker(&mutex);  // 加锁保护sendBuffer.enqueue(data);  // 添加到发送队列
}void TcpClientThread::onReadyRead()
{QByteArray data = tcpSocket->readAll();emit ClientInfor(1, data);  // 发射接收到的数据信号
}void TcpClientThread::onDisconnected()
{emit clientDisconnected();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/418678.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【word导出带图片】使用docxtemplater导出word,通知书形式的word

一、demo-导出的的 二、代码操作 1、页面呈现 项目要求&#xff0c;所以页面和导出来的word模版一致 2、js代码【直接展示点击导出的js代码】 使用插件【先下载这五个插件&#xff0c;然后页面引入插件】 import docxtemplater from docxtemplater import PizZip from pizzip …

LTE PSS主同步信号搜索 MATLAB实现

本期带来PSS相关检测说明和MATLAB实现&#xff0c;本期只讲相关方面的&#xff0c;所以MATLAB实现也是相关的部分&#xff0c;频偏估计方面的待下期开讲。 LTE 4G PSS搜索分为TDD搜索和FDD搜索&#xff0c;但是对于 TDD 和 FDD 而言&#xff0c;PSS同步信号的结构是完全一样的&…

sheng的学习笔记-AI-半监督聚类

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 半监督学习&#xff1a;sheng的学习笔记-AI-半监督学习-CSDN博客 聚类&#xff1a;sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 均值算法&#xff1a;sheng的学习笔记-AI-K均值算法_k均值算法怎么算迭代两次后的最大…

图形验证码从设计到实现

验证码的使用场景 图形验证码在我们的日常使用中是非常常见的&#xff0c;比如一些App、小程序、PC网站等。涉及到的业务也比较广泛、例如用户登录流程、注册流程、找回密码。下面我们来大致梳理下上述流程&#xff1a; 登录流程 用户首先在登录界面输入手机号然后通过图形验…

VMware时提示系统尚未修改安装失败

安装VMware安装失败&#xff0c;提示系统尚未修改 有以下解决方案&#xff1a; 1.操作系统不兼容 2.安装文件损坏 3.安装程序错误 4.硬件问题 解决&#xff1a;由于重装系统前&#xff0c;安装过VAware&#xff0c;所以应该操作系统&#xff0c;硬件没有问题。下载一个软件v…

关于Redis集群同步/持久化/淘汰机制的详解

Redis是非常常用的KV数据库, 使用内存以及HashMap进行存储的特点带来了高效的查询. 本文将围绕Redis的常见开发使用场景, 阐述在Redis集群中各个节点是如何进行数据同步, 每个节点如何进行持久化以及在长期使用中如何对数据进行更新和淘汰. 如果对Redis有更多的兴趣, 可以查看我…

Java中方法的使用详解

1.引言 假设有一个美女博主&#xff0c;每次发的照片都特别漂亮 然后该博主的评论区每次都会有很多粉丝的评论&#xff1a; 哇&#xff01;宝宝好漂亮&#xff0c;求上衣链接&#xff01;&#xff01;&#xff01; 老婆亲亲&#xff01;这个口红是什么色号呀&#xff1f; 宝…

【go】内存分配模型

内存是怎么分配给对象的&#xff1f; 内存分配优化的地方是&#xff1f; 讲讲golang内存分配模型&#xff1f; ans: 1.按照对象的大小分配&#xff1a;先算出对象的大小如果是tiny对象&#xff0c;就从tiny block中获取地址和偏移量&#xff0c;将对象打包到mcache;如果是16B以…

Python 在Excel中应用和取消多种不同类型的数据筛选

目录 安装Python Excel处理库 Python 在 Excel 中应用文本筛选 Python 在 Excel 中应用数字筛选 Python 在 Excel 中应用字体颜色、单元格颜色或图标集筛选 Python 在 Excel 中应用日期筛选 Python 在 Excel 中应用动态日期筛选 Python 在 Excel 中筛选空单元格或非空单…

【ArcGIS Pro第一期】界面简介

ArcGIS Pro简介 ArcGIS Pro界面简介1.1 打开工程1.2 使用功能区上的工具 参考 ArcGIS Pro 是一种基于功能区的应用程序。 ArcGIS Pro 窗口顶部的功能区有许多命令可供选择&#xff0c;而根据需要打开的各个窗格&#xff08;可停靠窗口&#xff09;中则提供了更为高级或专用的功…

快速排序(QuickSort)-归并排序(MergeSort)[java编写]

1. 快速排序 1.1 基本概述 快速排序采用分治思想&#xff0c;即在一个无序的序列中选取一个任意的基准元素pivot&#xff0c;利用pivot 将待排序的序列分成两部分&#xff0c;前面部分元素均小于或等于基准元素&#xff0c;后面部分均大于或等于基准元素&#xff0c;然后采用…

参会邀请 | 第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)

第二届机器视觉、图像处理与影像技术国际会议&#xff08;MVIPIT 2024&#xff09;将于2024年9月13日-15日在中国张家口召开。 MVIPIT 2024聚焦机器视觉、图像处理与影像技术&#xff0c;旨在为专家、学者和研究人员提供一个国际平台&#xff0c;分享研究成果&#xff0c;讨论…

算法训练营——day3长度最小子数组

1 长度最小子数组-力扣209&#xff08;中等&#xff09; 1.1 题目&#xff1a; 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返…

基于orangePi的智能家居系统

目录 一.接线图 1.orangePi接线 2.继电器接线 二.语音模块的配置 1.pin脚的配置 2.命令词自定义信息 三.测试 1.通过gpio指令测试烟雾检测器是否正确连接 2.编写脚本测试其他模组接线是否正常 四.人脸识别方案 1.首先开通人脸搜索识别服务 2. 点击产品控制台,向人…

2024年四川省安全员B证证考试题库及四川省安全员B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年四川省安全员B证证考试题库及四川省安全员B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

ARM----时钟

时钟频率可以是由晶振提供的&#xff0c;我们需要高频率&#xff0c;但是外部接高的晶振会不稳定&#xff0c;所有使用PLL&#xff08;锁相环&#xff09;来放大频率。接下来就让我们学习用外部晶振提供的频率来配置时钟频率。 一.时钟源的选择 在这里我们选择外部晶振作为时钟…

数据库面试题学习

B树和B树 B树 排好序的 节点内部有多个元素 B树 排好序的 节点内多个元素 叶子节点有指针&#xff08;双向指针&#xff09; 非叶子节点冗余了一份在叶子节点 mysql定义B树 InnoDB B树是B树的升级版~ InnoDB b树是怎么产生的 mysql 页 目录 16KB 自增id uuid 一页最多可以存储…

【精选】文件摆渡系统:跨网文件传输的安全与效率之选

文件摆渡系统可以解决哪些问题&#xff1f; 文件摆渡系统&#xff08;File Shuttle System&#xff09;主要是应用于不同网络、网段、区域之间的文件数据传输流转场景&#xff0c; 用于解决以下几类问题&#xff1a; 文件传输问题&#xff1a; 大文件传输&#xff1a;系统可…

Windows bat脚本学习九(srec_cat)

一、简介 srec_cat是一个在嵌入式开发中&#xff0c;使用非常频繁的软件&#xff0c;这里做个常用功能的介绍。 二、常用参数 文件类型 在使用srec_cat指令时&#xff0c;在输入文件和输出文件时&#xff0c;要指明文件的类型&#xff0c;如&#xff1a; input.hex -intel …