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

相关内容

热门资讯

安卓手机系统怎么变成ios系统... 你有没有想过,把你的安卓手机变成苹果手机呢?想象那光滑的屏幕、流畅的系统,还有那独特的苹果风格,是不...
安卓系统怎么省电模式,轻松延长... 手机电量总是不够用?别急,今天就来给你支几招,让你的安卓手机省电模式发挥最大功效,让你的手机续航能力...
安卓系统保持通话设置,全面解析... 亲爱的手机控们,你们有没有遇到过这样的情况:手机里的通话设置总是让人摸不着头脑,有时候明明想调整却怎...
监控舵机安卓系统下载,智能硬件... 你有没有想过,家里的机器人、无人机,甚至是你的手机,都可以成为你的“小眼睛”,随时随地帮你监控你想知...
安卓系统键盘文本替换,安卓系统... 手机里的文字输入是不是让你头疼?别急,今天就来给你揭秘安卓系统键盘文本替换的神奇魔法!想象那些重复的...
安卓系统能做车机系统吗,安卓系... 你有没有想过,那个我们天天不离手的安卓系统,竟然也能变成汽车的大脑?没错,就是那个能让你手机里装满各...
安卓12系统兼容不了,兼容性挑... 最近升级了安卓12系统,却发现好多应用都玩不转了,这可怎么办呢?别急,今天就来给你揭秘这个让人头疼的...
安卓系统连接到相机,安卓系统相... 你有没有想过,你的安卓手机和相机之间也能玩起“手拉手”的游戏呢?没错,就是那种通过高科技手段,让你的...
怎样从安卓系统转为ios系统,... 你有没有想过,把你的安卓手机变成苹果手机呢?想象那光滑的屏幕、流畅的操作,还有那独特的iOS系统,是...
十寸导航安卓系统,畅享科技魅力... 亲爱的车主朋友们,你们是不是也和我一样,对车里的导航系统有着超乎寻常的期待呢?想象在漫长的旅途中,有...
破解云电脑安卓系统,技术解析与... 哇塞,你有没有想过,你的手机也能变成一台强大的电脑?没错,就是那种可以运行各种复杂软件、畅玩大型游戏...
安卓系统打车推荐哪个,轻松选择 你有没有想过,在这个快节奏的城市里,叫一辆车竟然也能成为一种享受?没错,就是那种轻轻一点,就能轻松出...
安卓平板好用的系统,深度解析实... 你有没有想过,为什么安卓平板那么受欢迎呢?其实,这都得益于它们那些好用到飞起的系统!想象你拿着一块平...
开间小店安卓系统和ios系统,... 你知道吗?最近有一款游戏在手机圈里可是火得一塌糊涂,它就是《开间小店》!这款游戏不仅画风可爱,而且玩...
安卓系统怎么找root,安卓系... 亲爱的安卓手机用户们,你是否曾好奇过,如何给你的安卓手机找到那神秘的root权限呢?别急,今天我就要...
安卓系统 抖音升级,体验全新功... 你知道吗?最近安卓系统来了一场大变身,而抖音也跟着玩起了新花样,简直让人眼前一亮! 安卓系统:史上最...
考试系统平台推荐安卓,打造高效... 你还在为找一款好用的考试系统平台而烦恼吗?别急,今天我就要给你安利几款超赞的安卓考试系统平台,让你的...
安卓平板兼容windows系统... 你有没有想过,你的安卓平板电脑不仅能刷剧、玩游戏,还能变身成生产力工具?没错,就是那种兼容Windo...
暗区苹果系统转安卓系统,暗区玩... 亲爱的玩家们,你们是不是也和我一样,对暗区突围这款游戏爱得深沉呢?不过,换了个新手机,系统从苹果变成...
比小米系统好的安卓系统,探索更... 你有没有想过,手机系统就像是我们手机里的“灵魂”,它决定了我们的手机体验是流畅还是卡顿,是贴心还是繁...