Qt/C++开源项目 TCP服务器调试助手(源码分享+发布链接下载)
创始人
2024-09-25 05:20:13
0

该TCP服务器调试助手是用于测试和监控基于TCP协议的网络通信工具,能够帮助开发者便捷地进行网络通信调试。通过简洁的界面设计,用户可以轻松配置、管理TCP端口的连接,收发消息并进行数据监控分析。以下是该工具的主要功能:

1. 端口管理

  • 端口设置:用户可以在界面上设置服务器监听的端口号。在当前截图中,端口号被设置为123
  • 打开/关闭端口:用户可以通过点击“打开”或“关闭”按钮来启动或关闭指定端口。程序将监听该端口的TCP连接请求,并提供状态反馈。
  • 清空信息:通过“清空信息”和“清空接收”按钮,用户可以快速清除当前界面上显示的日志信息和接收到的消息,方便调试过程中清理数据。

2. 数据交互

  • 消息显示:程序可以显示详细的TCP通信记录,包括消息的发送时间消息内容以及发送状态(发送成功或接收成功)。界面上区分了发送和接收消息,发送消息显示为橙色,接收消息显示为绿色。
  • 通信消息格式:用户可选择以文本或HEX格式查看接收到的数据,并且可以通过界面勾选切换两种显示模式(例如:HEX显示和文本显示)。
  • 收发统计:程序提供了“收到帧数”、“发送帧数”、“收到字节”、“发送字节”等统计信息,帮助用户实时监控通信的数据量。

3. 群发功能

  • 定时群发:程序允许用户设置定时群发功能,用户可以向多个客户端定时发送消息。通过配置每个群发框,用户可以分别设置群发内容时间间隔(以毫秒为单位)。截图中默认时间间隔为1000毫秒,即每秒发送一次。
  • HEX发送选项:在发送数据时,用户可以选择是否将消息以HEX格式发送,灵活满足不同的通信需求。

4. 消息提示

  • 程序下方的提示窗口会显示实时的运行状态,例如:
    • 成功启动服务器并监听端口的提示;
    • 新客户端的连接信息(包含连接时间及客户端ID)。
  • 这些提示信息帮助用户快速了解当前通信状态并排查可能存在的连接问题。

5. 客户端连接管理

  • 连接显示:该工具不仅可以接收来自多个客户端的数据,还能显示每个客户端的唯一标识,如“客户端#1364”或“客户端#1380”,帮助用户有效管理多个连接。

6. 高度自定义

  • 动态配置发送消息:用户可以在程序界面中动态输入或修改即将发送的消息内容,并且在必要时可通过“清空”按钮快速重置待发送的消息。
  • 多消息通道:提供了多个消息发送输入框,方便用户针对不同的客户端或场景进行快速的消息群发操作。

发布软件下载链接

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

// tcpserver.h #ifndef TCPSERVER_H #define TCPSERVER_H  #include  #include  #include  #include   #define tc(a) QString::fromLocal8Bit(a)  class TcpServer : public QThread {     Q_OBJECT  public:     explicit TcpServer(QObject *parent = nullptr);     void run() override;                          // 线程入口点     bool startServer(int port);                   // 启动服务器     void closeServer();     void sendToAllClients(const QByteArray &message); // 群发消息     void sendToClient(qintptr socketDescriptor, const QByteArray &message); // 发送消息给指定客户端  signals:     void clientConnected(qintptr socketDescriptor);   // 新客户端连接信号     void clientDisconnected(qintptr socketDescriptor); // 客户端断开信号     void errors(int index, const QString &msg);      // 错误信号     void warnings(int index, const QString &msg);    // 警告信号     void informations(int index, const QString &msg); // 信息信号     void ClientInfor(const long long socketDescriptor,const QByteArray &msg,const bool isRecv) ;  ///<接收客户端信息  private slots:     void onNewConnection();                           // 新客户端连接时触发     void onClientDisconnected();                      // 客户端断开时触发     void onReadyRead();                               // 客户端有数据时触发  private:     QTcpServer *tcpServer;                            // TCP服务器     QMap clients;               // 保存客户端列表 }; #endif // TCPSERVER_H 

// tcpserver.cpp #include "tcpserver.h" #include  #include   TcpServer::TcpServer(QObject *parent)     : QThread(parent), tcpServer(nullptr) { }  void TcpServer::run() {     exec();  // 启动线程事件循环 }  // 启动服务器并监听指定端口 bool TcpServer::startServer(int port) {     tcpServer = new QTcpServer();      if (!tcpServer->listen(QHostAddress::Any, static_cast(port)))     {         emit errors(1, tc("服务器启动失败:%1 端口: ").arg(tcpServer->errorString()) + QString::number(port));         return false;     }      connect(tcpServer, &QTcpServer::newConnection, this, &TcpServer::onNewConnection);     emit informations(1, tc("服务器启动成功,监听端口: ") + QString::number(port));      return true; }  void TcpServer::closeServer() {     tcpServer->close(); }  // 当有新客户端连接时 void TcpServer::onNewConnection() {     QTcpSocket *clientSocket = tcpServer->nextPendingConnection();     qintptr socketDescriptor = clientSocket->socketDescriptor();      clients.insert(socketDescriptor, clientSocket);  // 添加到客户端列表      connect(clientSocket, &QTcpSocket::disconnected, this, &TcpServer::onClientDisconnected);     connect(clientSocket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);      emit clientConnected(socketDescriptor);  // 触发客户端连接信号     emit informations(2, tc("新的客户端连接,描述符: ") + QString::number(socketDescriptor)); }  // 当客户端断开连接时 void TcpServer::onClientDisconnected() {     QTcpSocket *clientSocket = qobject_cast(sender());     if (clientSocket)     {         qintptr socketDescriptor=0;         for (auto key : clients.keys()) {              if(clients[key]==clientSocket)                 socketDescriptor = key;         }         clients.remove(socketDescriptor);  // 从客户端列表中移除         emit clientDisconnected(socketDescriptor);  // 触发客户端断开信号         emit warnings(1, tc("客户端断开连接,描述符: ") + QString::number(socketDescriptor));         clientSocket->deleteLater();     } }  // 当有客户端发送数据时 void TcpServer::onReadyRead() {     QTcpSocket *clientSocket = qobject_cast(sender());     if (clientSocket) {         QByteArray data = clientSocket->readAll();         emit ClientInfor(clientSocket->socketDescriptor(), data,true);     } }  // 群发消息 void TcpServer::sendToAllClients(const QByteArray &message) {      if(clients.keys().isEmpty())     {         emit errors(1, tc("未存在可发送的客户端 "));         return;     }      for(auto key:clients.keys())         sendToClient(key,message); }  // 发送消息给指定客户端 void TcpServer::sendToClient(qintptr socketDescriptor, const QByteArray &message) {     QTcpSocket *clientSocket = clients.value(socketDescriptor, nullptr);     if (clientSocket)     {         clientSocket->write(message);         emit ClientInfor(clientSocket->socketDescriptor(), message,false);     } else {         emit errors(2, tc("无法找到指定的客户端,描述符: ") + QString::number(socketDescriptor));     } } 
// mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H  #include  #include  #include "tcpserver.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_OBJECT  public:     MainWindow(QWidget *parent = nullptr);     ~MainWindow();     void initStyle();        //创建发送框     void createSendLinEdit();  private slots:     void on_startServerButton_clicked();              // 点击启动服务器按钮     void on_stopserverButton_clicked();     void onClientConnected(qintptr socketDescriptor); // 客户端连接信号槽     void onClientDisconnected(qintptr socketDescriptor); // 客户端断开信号槽     void handleErrors(int index, const QString &msg);      // 处理错误信号槽     void handleWarnings(int index, const QString &msg);    // 处理警告信号槽     void handleInformations(int index, const QString &msg); // 处理信息信号槽     void handlerClientInfor(const long long id,const QByteArray &data,const bool isRecv);     void writeRunTimeMsgs(const QString &msg, const int level); // 输出运行时消息         void on_clearRunTimeutton_clicked();      void on_clearRecvButton_clicked();      void on_closeTip_clicked();  private:     Ui::MainWindow *ui;     TcpServer *server;                     // TCP服务器     QStandardItemModel *model; // 共享数据模型 }; #endif // MAINWINDOW_H 
// mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include  #include  #include  #include "timesendwidget.h" MainWindow::MainWindow(QWidget *parent)     : QMainWindow(parent)     , ui(new Ui::MainWindow)     , server(new TcpServer())  // 初始化服务器 {     ui->setupUi(this);       // 连接服务器信号槽     connect(server, &TcpServer::clientConnected, this, &MainWindow::onClientConnected);     connect(server, &TcpServer::clientDisconnected, this, &MainWindow::onClientDisconnected);     connect(server, &TcpServer::errors, this, &MainWindow::handleErrors);     connect(server, &TcpServer::warnings, this, &MainWindow::handleWarnings);     connect(server, &TcpServer::informations, this, &MainWindow::handleInformations);     connect(server, &TcpServer::ClientInfor, this, &MainWindow::handlerClientInfor);        // 创建共享的数据模型     model = new QStandardItemModel(this);      QStandardItem *item = new QStandardItem(tc("群发"));     item->setData(-1,Qt::UserRole);     model->appendRow(item);      createSendLinEdit();     initStyle(); }  MainWindow::~MainWindow() {     delete ui;     server->quit();  // 退出服务器线程     server->wait();  // 等待线程结束     delete server; }  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()); #endif         QString 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;         sendWidget->setComBoxModel(model);         connect(sendWidget,&TimeSendWidget::sendLineData,[=](const qintptr socketDescriptor,const QByteArray &data )         {              if(data.isEmpty())             {                 writeRunTimeMsgs(tc("信息为空,拒绝发送"),Warning);                 return ;             }              ((socketDescriptor<0)? server->sendToAllClients(data): server->sendToClient(socketDescriptor, data));             });         ui->verticalLayout->addWidget(sendWidget);     } }   // 启动服务器按钮 void MainWindow::on_startServerButton_clicked() {     int port = ui->portspinBox->value();     if (port > 0) {         if (server->startServer(port))         {             writeRunTimeMsgs(tc("服务器成功启动,监听端口:") + QString::number(port), 2);             ui->startServerButton->setEnabled(false);         } else {             writeRunTimeMsgs(tc("服务器启动失败!"), 0);         }     } else {         writeRunTimeMsgs(tc("无效的端口号!"), 1);     } } // 关闭服务器按钮 void MainWindow::on_stopserverButton_clicked() {     server->closeServer();     ui->startServerButton->setEnabled(true);  } // 处理客户端连接的槽函数 void MainWindow::onClientConnected(qintptr socketDescriptor) {     writeRunTimeMsgs(tc("客户端连接,描述符: ") + QString::number(socketDescriptor), 2);      QStandardItem *item = new QStandardItem(tc("客户端#%1").arg(socketDescriptor));     item->setData(socketDescriptor,Qt::UserRole);     model->appendRow(item);   }  // 处理客户端断开的槽函数 void MainWindow::onClientDisconnected(qintptr socketDescriptor) {     writeRunTimeMsgs(tc("客户端断开连接,描述符: ") + QString::number(socketDescriptor), 1);      // 从客户端列表中移除     for (int i = 0; i < model->rowCount(); ++i)     {         QStandardItem *item = model->item(i);         if (item && item->data(Qt::UserRole).toLongLong() == socketDescriptor)         {              model->removeRow(i);  // 删除找到的行             break;  // 如果只想删除第一个匹配的项,删除后直接跳出循环         }     } }  // 处理错误信号 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 long long id, const QByteArray &data, const bool isRecv) {      QString prefix;     QString color;     QString msg=tc("%1客户端#%2: %3").arg(isRecv?tc("接收←"):tc("发送→")).arg(id).arg(ui->isShowHexButton->isChecked()? data.toHex(' ').toUpper():QString::fromLocal8Bit(data));      if(isRecv)     {          //更新显示信息         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("%2 %3: %4").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("%2 %3: %4").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()); } 

相关内容

热门资讯

华为安卓8.0系统蓝牙,华为安... 你知道吗?最近华为出了一款新手机,搭载的是安卓8.0系统,而且蓝牙功能超级强大!今天,我就来给你详细...
鸿蒙系统怎样恢复安卓,轻松恢复... 你有没有遇到过手机系统崩溃的尴尬时刻?尤其是当你正沉浸在鸿蒙系统的美妙体验中,突然发现它“罢工”了,...
安卓系统能换ios系统文件,系... 你知道吗?现在科技的发展真是让人眼花缭乱,连手机系统都能来个“大变身”呢!没错,就是那个我们熟悉的安...
安卓系统发热会卡吗,安卓手机发... 手机发热卡顿,是不是让你头疼不已?尤其是安卓系统,有时候一发热就感觉像是慢吞吞的老牛,让人抓狂。今天...
安卓window双系统用处,多... 你有没有想过,为什么有些人手机里既有安卓系统,又有Windows系统呢?这可不是简单的爱好,而是有着...
安卓系统清理底层垃圾,底层垃圾... 手机用久了是不是感觉越来越慢了?别急,今天就来给你支个招,让你的安卓手机焕然一新,速度飞快!那就是—...
易语言开发安卓系统,创新编程语... 你有没有想过,用我们熟悉的中文编程语言来开发安卓系统呢?这听起来是不是有点不可思议?但你知道吗,易语...
合并安卓系统分区,安卓系统分区... 你有没有想过,你的安卓手机里那些神秘的系统分区,其实是可以被你巧妙地合并的?没错,就是那个让不少手机...
安卓手机升级系统更新,探索新功... 亲爱的手机控们,你们有没有发现,最近你的安卓手机好像变得有些不一样了呢?是不是觉得它变得更加流畅,功...
安卓系统基于什么底层,基于Li... 你有没有想过,安卓系统这个我们每天不离手的家伙,它到底是怎么运作的呢?它背后的秘密,是不是就像一部复...
安卓系统8.0如何更新,轻松实... 亲爱的安卓用户们,你是否也像我一样,对安卓系统8.0的新鲜功能充满期待呢?想要让你的手机焕然一新,体...
安卓手机拦截系统下载,下载安全... 你有没有遇到过这种情况:手机里突然弹出了各种广告,或者收到了一些奇怪的短信,让你不禁怀疑自己的手机是...
安卓调用系统相机代码,Andr... 你有没有想过,手机里的相机功能竟然可以这么神奇地被我们调用?没错,就是那个安卓系统里的相机,它不仅能...
安卓系统威图手机,安卓系统下的... 你知道吗?在手机市场上,有一款特别引人注目的手机,那就是安卓系统下的威图手机。它不仅外观时尚,功能强...
把电脑装上安卓系统,安卓系统在... 你有没有想过,把你的电脑装上安卓系统,让它瞬间变身成一部超级手机?想象你可以在电脑上玩手游、刷抖音,...
安卓系统更新特别慢,探究原因与... 你有没有发现,安卓系统的更新速度简直让人抓狂?每次看到手机屏幕上那个小小的更新提示,心里就一阵烦躁。...
安卓10的系统文件,深度解析与... 你知道吗?最近安卓系统又升级啦!安卓10的系统文件可是大有来头,今天就来给你好好扒一扒这个神秘的家伙...
维修安装系统安卓版,便捷高效的... 你有没有遇到过手机或者电脑出了点小状况,心里那个急啊,但又不知道怎么办?别担心,今天就来给你安利一个...
安卓系统右上图标,功能解析与使... 你有没有注意到,每次打开安卓手机,右上角那个小小的图标,它就像一个默默无闻的小卫士,静静地守护着你的...
微软安卓系统怎么用,轻松上手与... 亲爱的安卓用户们,你是否曾好奇过,那些在Windows系统上如鱼得水的应用,如何在安卓系统上也能发挥...