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()); } 

相关内容

热门资讯

原生安卓系统哪个最好使,探寻最... 亲爱的手机控们,你是否在寻找一款能让你爱不释手的原生安卓系统呢?今天,就让我带你一起探索,看看哪个原...
安卓系统扫描仪软件,轻松捕捉每... 你有没有想过,手机也能变成强大的扫描仪?没错,就是那个你每天不离手的安卓手机!今天,就让我带你一起探...
安卓系统webview要更新吗... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,这可能是你的安卓系统WebView需要...
安卓哪个系统最帅气,探寻最帅气... 你有没有发现,手机系统就像是个人的风格,有的低调内敛,有的张扬个性。今天,咱们就来聊聊安卓系统里哪个...
闪耀暖暖安卓系统卡,探寻解决之... 最近是不是有很多小伙伴在玩《闪耀暖暖》这款游戏呢?不过,有些小伙伴在体验过程中遇到了一个让人头疼的问...
酷开系统装安卓app,畅享海量... 你有没有发现,家里的电视突然变得聪明起来?没错,就是那个酷开系统,它现在可是装安卓app的高手呢!今...
安卓系统通话息屏,通话无忧 你有没有遇到过这种情况:手机屏幕熄灭了,但电话却还在响个不停?是不是觉得有点尴尬,又有点无奈?别担心...
支持安卓系统的导航,支持安卓系... 你有没有想过,在手机上安装一款支持安卓系统的导航软件,就像是给你的出行装上了“顺风耳”和“千里眼”呢...
安卓系统启动机制,揭秘启动流程... 你有没有想过,当你按下那个小小的开机键,安卓系统是如何从沉睡中苏醒,开始它的一天呢?今天,就让我带你...
安卓装系统用什么软件,精选软件... 你有没有想过,你的安卓手机或者平板,有一天突然想要换换口味,换一个全新的操作系统呢?别急,今天就来给...
wps安卓系统如何横屏,文章的... 你有没有发现,用WPS在安卓系统上办公的时候,横屏模式简直太方便了!想象屏幕宽广,文字清晰,是不是瞬...
TCL电视搭载安卓系统,畅享智... 亲爱的读者们,你是否在寻找一款既时尚又实用的电视呢?今天,我要给你介绍一款特别受欢迎的电视——TCL...
安卓系统qq动态怎么删,一键操... 你是不是也有过这样的烦恼?手机里QQ动态堆得像小山,想删又不知道怎么下手?别急,今天就来手把手教你如...
安卓手机的系统游戏,解锁手机游... 你有没有发现,安卓手机的系统游戏越来越丰富了呢?没错,现在就让我带你一起探索这个充满乐趣的世界吧!一...
安卓系统ui流畅排名,谁才是流... 你有没有发现,手机用久了,有时候操作起来就像蜗牛爬行一样慢吞吞的?这不,最近我在网上闲逛,无意间发现...
安卓系统怎么连接音响蓝牙,安卓... 你家的安卓手机是不是已经更新到了最新的系统,音响也换成了那个高大上的蓝牙款?但是,连接起来却有点小麻...
炸金花如何开好友房间房卡/嫦娥... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信链接炸金花房卡怎样买/欢乐... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信牛牛房卡自建房间/战皇大厅... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
微信牛牛房卡如何购买/美猴王大... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受更...