QT学习——简易网络调试助手

目录

1.界面预览

1.1服务端界面

1.2客户端界面

2.代码分析 

2.1开发流程

2.2QTcpServer QTcpSocket 类

 2.3数据的接收和发送

 2.4添加客户端的端口号

2.5服务端完整代码 

2.5.1widget.h

2.5.2widget.cpp

2.5.3qmycomboBox.h

2.5.3qmycomboBox.cpp

2.6客户端完整代码

 2.6.1widget.h

2.6.2widget.cpp


1.界面预览

1.1服务端界面

1.2客户端界面

  •  控件就不多介绍了 

2.代码分析 

2.1开发流程

2.2QTcpServer QTcpSocket 类

既然要万物互联了学习网络的知识就变的至关重要了。

QTcpServer类提供了一个基于TCP的服务器。这个类使得接受传入的TCP连接成为可能。

QTcpSocket 类提供了一个TCP套接字。
QTcpSocket 是 QAbstractSocket 的一个方便子类,允许你建立TCP连接并传输数据流

调用 listen() 来让服务器开始监听传入的连接。每当客户端连接到服务器时,就会发射 newConnection() 信号。

调用 nextPendingConnection() 来接受等待中的连接作为一个已连接的 QTcpSocket。这个函数会返回一个指向处于 QAbstractSocket::ConnectedState 状态的 QTcpSocket 指针,你可以用它与客户端进行通信。

如果发生错误,serverError() 返回错误类型,可以调用 errorString() 来获得发生错误的人类可读描述。

当监听连接时,服务器正在监听的地址和端口可以通过 serverAddress() 和 serverPort() 获得。

调用 close() 会使 QTcpServer 停止监听传入的连接。

尽管 QTcpServer 主要设计用于与事件循环一起使用,但也可以在没有事件循环的情况下使用。在这种情况下,你必须使用 waitForNewConnection(),它会阻塞直到连接可用或超时。

QTcpServer *tcpServer;
tcpServer = new QTcpServer(this);//QTcpServer 类提供基于 TCP 的服务器
//监听客户端的连接
void Widget::on_pushButtonStartList_clicked()
{
    //监听指定的地址和端口
    if(!tcpServer->listen(QHostAddress(ui->comboBoxaddr->currentText()),ui->lineEditport->text().toInt())){
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("端口号可能被占用");
        msgBox.exec();
        return;
    }
    //当监听按键按下后按键的状态
    ui->pushButtonStartList->setEnabled(false);
    ui->pushButtonStopList->setEnabled(true);
    ui->pushButtonDuankai->setEnabled(true);
}
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(on_ClientTcpConnect_slot()));
//有客户端连接
void Widget::on_ClientTcpConnect_slot()
{
    //检查是否有挂起的连接请求等待被接受
    if(tcpServer->hasPendingConnections()){
        QTcpSocket *tcpSocket = tcpServer->nextPendingConnection(); //将挂起的连接接受为已连接的QTcpSocket,通过该对象可以与客户端通信。
        ui->textEditRev->insertPlainText("cilent addr:" + tcpSocket->peerAddress().toString() + "\n" +
                                         "cilent port:" + QString::number(tcpSocket->peerPort()));
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_readCilentData_Slot()));//读取客户端数据的信号与槽
        //connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_ClientDisconnect_Slot()));//客户端断开的信号与槽1
        connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
                SLOT(on_StateChanged_Slot(QAbstractSocket::SocketState)));//客户端断开的信号与槽2
        ui->comboBoxClientPort->addItem(QString::number(tcpSocket->peerPort()));//将获取的端口号添加到QComboBox中
        ui->comboBoxClientPort->setCurrentText(QString::number(tcpSocket->peerPort()));//设置为当前连接的端口号
        //如果有新的客户端连接就启用发送按键
        if(!ui->pushButtonSend->isEnabled()){
            ui->pushButtonSend->setEnabled(true);
        }
    }
}
  • 这样就可以连接到客户端了

 2.3数据的接收和发送

qobject_cast 函数,它是 Qt 提供的一个用于执行安全的类型转换的函数。在这里,它尝试将 sender() 返回的指针转换为 QTcpSocket 类型的指针。

sender() 返回发送信号的对象的指针。

//读取客户端数据
void Widget::on_readCilentData_Slot()
{
    QTcpSocket *tmpreadBuf = qobject_cast<QTcpSocket *>(sender());//获取发送信号对象的指针
    QByteArray readBuf = tmpreadBuf->readAll();//接收客户端的数据
    ui->textEditRev->insertPlainText("\n" + readBuf);

    ui->textEditRev->moveCursor(QTextCursor::End);//跟随光标移动
    ui->textEditRev->ensureCursorVisible();//确保光标是可视的
}

findChildren<QTcpSocket *>() 函数,它是 QObject 类的成员函数。这个函数会在 tcpServer 对象的子对象中查找并返回所有类型为 QTcpSocket 的子对象的指针列表。(这里我们要和所有的客户端进行通信所以要获取全部的QTcpSocket)

//发送按键
void Widget::on_pushButtonSend_clicked()
{
    QList<QTcpSocket *> revClients = tcpServer->findChildren<QTcpSocket *>();//获取到客户端并添加到数组里
    //检查有无客户端连接  就是判断一下QComboBox是否为空
    if(revClients.isEmpty()){
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("无连接");
        msgBox.exec();
        return;
    }
    if(ui->comboBoxClientPort->currentText() != "Client All"){
        QString tmpSendstr = ui->comboBoxClientPort->currentText();//获取当前的客户端端口号
        for(QTcpSocket *tmp : revClients){
            //通过比较当前和客户端的端口号进行数据的发送
            if(QString::number(tmp->peerPort()) == tmpSendstr){
                tmp->write(ui->lineEditSend->text().toStdString().c_str());//向客户端发送数据
            }
        }
    }else{
        for(QTcpSocket *tmprevClients : revClients){
            tmprevClients->write(ui->lineEditSend->text().toStdString().c_str());
        }
    }
}

 2.4添加客户端的端口号

  • 重写事件处理函数来处理特定的事件 
void QMyComBoBox::mousePressEvent(QMouseEvent *e)
{
    //检测鼠标左键按下
    if(e->button() == Qt::LeftButton){
        //发送自定义的信号
        emit falshComboBox();
    }
    //让程序可以继续执行
    QComboBox::mousePressEvent(e);
}
connect(ui->comboBoxClientPort, &QMyComBoBox::falshComboBox,this,
            &Widget::on_ClientFalshProtComboBox_Slot);//刷新QComboBox
//鼠标左键点击后可以刷新QComboBox
void Widget::on_ClientFalshProtComboBox_Slot()
{
    ui->comboBoxClientPort->clear();
    QList<QTcpSocket *> getClientsPort = tcpServer->findChildren<QTcpSocket *>();//获取到客户端并添加到数组里
    for(QTcpSocket *tmpgetClientsPort : getClientsPort){
        if(tmpgetClientsPort != nullptr)
            ui->comboBoxClientPort->addItem(QString::number(tmpgetClientsPort->peerPort()));//将端口添加到QComboBox中
    }
    ui->comboBoxClientPort->addItem("Client All");
}
  • 剩下的断开和停止监听比较简单就不多介绍了 

2.5服务端完整代码 

2.5.1widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>

#include "qmycombobox.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    //创建TCP服务器的对象
    QTcpServer *tcpServer;

public slots:
    //有客户端连接
    void on_ClientTcpConnect_slot();

    //读取客户端数据
    void on_readCilentData_Slot();

    //客户端断开连接的实现1
    //void on_ClientDisconnect_Slot();

    //客户端断开连接的实现2
    void on_StateChanged_Slot(QAbstractSocket::SocketState socketState);

    //鼠标左键点击后可以刷新QComboBox
    void on_ClientFalshProtComboBox_Slot();

private slots:
    //监听客户端的连接
    void on_pushButtonStartList_clicked();

    //发送按键
    void on_pushButtonSend_clicked();

    //停止监听新的客户端
    void on_pushButtonStopList_clicked();

    //与客户端断开
    void on_pushButtonDuankai_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

2.5.2widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QNetworkInterface>
#include <QTcpSocket>
#include <QIODevice>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    tcpServer = new QTcpServer(this);//QTcpServer 类提供基于 TCP 的服务器

    //按键初始化的状态
    ui->pushButtonStartList->setEnabled(true);
    ui->pushButtonStopList->setEnabled(false);
    ui->pushButtonDuankai->setEnabled(false);
    ui->pushButtonSend->setEnabled(false);

    //当有新的TCP连接,会触发newConnection()信号
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(on_ClientTcpConnect_slot()));
    connect(ui->comboBoxClientPort, &QMyComBoBox::falshComboBox,this,
            &Widget::on_ClientFalshProtComboBox_Slot);//刷新QComboBox

    //获取pc的ip地址:QList<QHostAddress> QNetworkInterface::allAddresses()
    QList<QHostAddress> comboBoxaddr = QNetworkInterface::allAddresses();
    for(QHostAddress tmpAddr : comboBoxaddr){
        if(tmpAddr.protocol() == QAbstractSocket::IPv4Protocol){//过滤出IPV4的地址
            ui->comboBoxaddr->addItem(tmpAddr.toString());
        }
    }
    //comboBox初始化的状态
    ui->comboBoxaddr->setCurrentIndex(2);
}

Widget::~Widget()
{
    delete ui;
}

//有客户端连接
void Widget::on_ClientTcpConnect_slot()
{
    //检查是否有挂起的连接请求等待被接受
    if(tcpServer->hasPendingConnections()){
        QTcpSocket *tcpSocket = tcpServer->nextPendingConnection(); //将挂起的连接接受为已连接的QTcpSocket,通过该对象可以与客户端通信。
        ui->textEditRev->insertPlainText("cilent addr:" + tcpSocket->peerAddress().toString() + "\n" +
                                         "cilent port:" + QString::number(tcpSocket->peerPort()));
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_readCilentData_Slot()));//读取客户端数据的信号与槽
        //connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(on_ClientDisconnect_Slot()));//客户端断开的信号与槽1
        connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
                SLOT(on_StateChanged_Slot(QAbstractSocket::SocketState)));//客户端断开的信号与槽2
        ui->comboBoxClientPort->addItem(QString::number(tcpSocket->peerPort()));//将获取的端口号添加到QComboBox中
        ui->comboBoxClientPort->setCurrentText(QString::number(tcpSocket->peerPort()));//设置为当前连接的端口号
        //如果有新的客户端连接就启用发送按键
        if(!ui->pushButtonSend->isEnabled()){
            ui->pushButtonSend->setEnabled(true);
        }
    }
}

//读取客户端数据
void Widget::on_readCilentData_Slot()
{
    QTcpSocket *tmpreadBuf = qobject_cast<QTcpSocket *>(sender());//获取发送信号对象的指针
    QByteArray readBuf = tmpreadBuf->readAll();//接收客户端的数据
    ui->textEditRev->insertPlainText("\n" + readBuf);

    ui->textEditRev->moveCursor(QTextCursor::End);//跟随光标移动
    ui->textEditRev->ensureCursorVisible();//确保光标是可视的
}

//客户端断开连接的实现1
//void Widget::on_ClientDisconnect_Slot()
//{
//    QTcpSocket *_tmpreadBuf = qobject_cast<QTcpSocket *>(sender());
//    ui->textEditRev->insertPlainText("\n客户端断开连接\n");
//    _tmpreadBuf->deleteLater();
//}

//客户端断开连接的实现2
void Widget::on_StateChanged_Slot(QAbstractSocket::SocketState socketState)
{
    int tmpindex;
    QTcpSocket *_tmpreadBuf = qobject_cast<QTcpSocket *>(sender());//获取发送信号对象的指针

    switch(socketState){
    //连接断开状态
    case QAbstractSocket::UnconnectedState:
        ui->textEditRev->insertPlainText("\n客户端断开连接\n");
        tmpindex = ui->comboBoxClientPort->findText(QString::number(_tmpreadBuf->peerPort()));//在文本控件中搜索指定的文本,并返回匹配的位置
        qDebug() << QString::number(_tmpreadBuf->peerPort());
        qDebug() << tmpindex;
        ui->comboBoxClientPort->removeItem(tmpindex);
        _tmpreadBuf->deleteLater();//延迟删除对象
        qDebug() <<ui->comboBoxClientPort->count();
        if(ui->comboBoxClientPort->count() == 0)
            ui->pushButtonSend->setEnabled(false);
        break;
    //连接状态
    case QAbstractSocket::ConnectingState:
    case QAbstractSocket::ConnectedState:
        ui->textEditRev->insertPlainText("\n客户端连接\n");
        break;
    }
}

//鼠标左键点击后可以刷新QComboBox
void Widget::on_ClientFalshProtComboBox_Slot()
{
    ui->comboBoxClientPort->clear();
    QList<QTcpSocket *> getClientsPort = tcpServer->findChildren<QTcpSocket *>();//获取到客户端并添加到数组里
    for(QTcpSocket *tmpgetClientsPort : getClientsPort){
        if(tmpgetClientsPort != nullptr)
            ui->comboBoxClientPort->addItem(QString::number(tmpgetClientsPort->peerPort()));//将端口添加到QComboBox中
    }
    ui->comboBoxClientPort->addItem("Client All");
}

//监听客户端的连接
void Widget::on_pushButtonStartList_clicked()
{
    //监听指定的地址和端口
    if(!tcpServer->listen(QHostAddress(ui->comboBoxaddr->currentText()),ui->lineEditport->text().toInt())){
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("端口号可能被占用");
        msgBox.exec();
        return;
    }
    //当监听按键按下后按键的状态
    ui->pushButtonStartList->setEnabled(false);
    ui->pushButtonStopList->setEnabled(true);
    ui->pushButtonDuankai->setEnabled(true);
}

//发送按键
void Widget::on_pushButtonSend_clicked()
{
    QList<QTcpSocket *> revClients = tcpServer->findChildren<QTcpSocket *>();//获取到客户端并添加到数组里
    //检查有无客户端连接  就是判断一下QComboBox是否为空
    if(revClients.isEmpty()){
        QMessageBox msgBox;
        msgBox.setWindowTitle("错误");
        msgBox.setText("无连接");
        msgBox.exec();
        return;
    }
    if(ui->comboBoxClientPort->currentText() != "Client All"){
        QString tmpSendstr = ui->comboBoxClientPort->currentText();//获取当前的客户端端口号
        for(QTcpSocket *tmp : revClients){
            //通过比较当前和客户端的端口号进行数据的发送
            if(QString::number(tmp->peerPort()) == tmpSendstr){
                tmp->write(ui->lineEditSend->text().toStdString().c_str());//向客户端发送数据
            }
        }
    }else{
        for(QTcpSocket *tmprevClients : revClients){
            tmprevClients->write(ui->lineEditSend->text().toStdString().c_str());
        }
    }
}

//停止监听新的客户端
void Widget::on_pushButtonStopList_clicked()
{
    QList<QTcpSocket *> revClients = tcpServer->findChildren<QTcpSocket *>();//获取到客户端并添加到数组里

    for(QTcpSocket *tmprevClients : revClients){
        tmprevClients->close();//关闭所有的QTcpSocket 连接,
    }
    tcpServer->close();//停止监听新的连接请求
    ui->pushButtonStartList->setEnabled(true);
    ui->pushButtonStopList->setEnabled(false);
    ui->pushButtonDuankai->setEnabled(false);
    ui->pushButtonSend->setEnabled(false);
}

//与客户端断开
void Widget::on_pushButtonDuankai_clicked()
{
    //停止监听新的客户端
    on_pushButtonStopList_clicked();
    //卸载掉TCP服务器
    delete tcpServer;
    this->close();
}

2.5.3qmycomboBox.h

#ifndef QMYCOMBOBOX_H
#define QMYCOMBOBOX_H

#include <QComboBox>
#include <QWidget>

class QMyComBoBox : public QComboBox
{
    Q_OBJECT
public:
    QMyComBoBox(QWidget *parent);
protected:
    void mousePressEvent(QMouseEvent *e) override;
signals:
    void falshComboBox();
};

#endif // QMYCOMBOBOX_H

2.5.3qmycomboBox.cpp

#include "qmycombobox.h"

#include <QMouseEvent>

QMyComBoBox::QMyComBoBox(QWidget *parent) : QComboBox(parent)
{

}

void QMyComBoBox::mousePressEvent(QMouseEvent *e)
{
    //检测鼠标左键按下
    if(e->button() == Qt::LeftButton){
        //发送自定义的信号
        emit falshComboBox();
    }
    //让程序可以继续执行
    QComboBox::mousePressEvent(e);
}

2.6客户端完整代码

 2.6.1widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QTcpSocket>
#include <QTimer>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:

    //连接服务端
    void on_pushButtonConnect_clicked();

    //接收服务端的数据
    void on_readServerData_Slot();

    //发送数据到服务端
    void on_pushButtonSend_clicked();

    //断开服务端
    void on_pushButtonDisconnect_clicked();

    //成功连接服务端的操作
    void on_connect_Slot();

    //连接服务端发生错误
    void on_error_Slot(QAbstractSocket::SocketError error);

    //定时时间超时
    void on_timerout_Slot();

private:
    Ui::Widget *ui;

    QTcpSocket *client;//创建一个QTcpSocket对象
    QTimer *timer;//创建一个定时器的对象

    //文本字体颜色的转换
    void colorConver(Qt::GlobalColor color, QString str);
};
#endif // WIDGET_H

2.6.2widget.cpp

 QTextCharFormat 是 Qt 中用于描述文本字符格式的类。它包含了文本的各种格式属性,比如字体、颜色、背景色、文本样式(粗体、斜体等)等。QTextCharFormat 类通常用于富文本编辑和格式化文本显示。

可以使用 QTextCharFormat 类来设置文本的格式,例如:

设置字体:setFont()
设置字体大小:setFontSize()
设置字体颜色:setForeground()
设置背景色:setBackground()
设置文本样式:setFontWeight(), setFontItalic(), setFontUnderline(), setFontStrikeOut()
设置超链接:setAnchor(), setAnchorHref()
等等
通过创建一个 QTextCharFormat 对象,可以为文本添加不同的格式,然后应用到相应的文本段落或文本块中

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    client = new QTcpSocket(this);

    ui->pushButtonDisconnect->setEnabled(false);//断开按键初始化的状态
    ui->pushButtonSend->setEnabled(false);//发送按键初始化的状态

    connect(client, SIGNAL(readyRead()), this, SLOT(on_readServerData_Slot()));//读取服务端数据的
}

Widget::~Widget()
{
    delete ui;
}

//连接服务端
void Widget::on_pushButtonConnect_clicked()
{
    timer = new QTimer;
    timer->setInterval(5000);//设置定时器的时间为5秒
    timer->setSingleShot(true);//设置定时器单次触发模式

    client->connectToHost(ui->lineEditIP->text(), ui->lineEditProt->text().toInt());//连接主机
    connect(client, SIGNAL(connected()), this, SLOT(on_connect_Slot()));//成功连接到服务端
    connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(on_error_Slot(QAbstractSocket::SocketError)));//连接服务端错误
    connect(timer,  SIGNAL(timeout()), this, SLOT(on_timerout_Slot()));
    this->setEnabled(false);//当点击连接时UI界面不可选
    timer->start();//启动定时器
}

//接收服务端的数据
void Widget::on_readServerData_Slot()
{
    colorConver(Qt::black, client->readAll());//读取服务端数据
}

//发送数据到服务端
void Widget::on_pushButtonSend_clicked()
{
    client->write(ui->textEditSend->toPlainText().toUtf8());//发送数据到服务端
    colorConver(Qt::red, ui->textEditSend->toPlainText().toUtf8());//将颜色转换为
}

//断开服务端
void Widget::on_pushButtonDisconnect_clicked()
{
   client->close();//关闭QTcpSocket
   //UI显示设置
   ui->textEditeRev->append("已断开");
   ui->pushButtonConnect->setEnabled(true);
   ui->lineEditIP->setEnabled(true);
   ui->lineEditProt->setEnabled(true);
   ui->pushButtonDisconnect->setEnabled(false);
   ui->pushButtonSend->setEnabled(false);
}

//成功连接服务端的操作
void Widget::on_connect_Slot()
{
    timer->stop();
    this->setEnabled(true);//连接成功时UI界面可选
    //UI显示设置
    ui->textEditeRev->append("已连接");
    ui->pushButtonConnect->setEnabled(false);
    ui->lineEditIP->setEnabled(false);
    ui->lineEditProt->setEnabled(false);
    ui->pushButtonDisconnect->setEnabled(true);
    ui->pushButtonSend->setEnabled(true);
}

//连接服务端发生错误
void Widget::on_error_Slot(QAbstractSocket::SocketError error)
{
    this->setEnabled(true);//连接错误时UI界面可选
    client->abort();//立即关闭当前的TCP连接
    ui->textEditeRev->append("连接错误,可能服务器断开");
    on_pushButtonDisconnect_clicked();//断开服务端
}

//定时时间超时
void Widget::on_timerout_Slot()
{
   ui->textEditeRev->insertPlainText("连接超时!");
   this->setEnabled(true);//定时时间到时UI界面可选
}

//文本字体颜色的转换
void Widget::colorConver(Qt::GlobalColor color, QString str)
{
    QTextCursor cursor =  ui->textEditeRev->textCursor();//获取当前光标位置
    QTextCharFormat format;

    format.setForeground(QBrush(color));//设置文本前景色的函数
    cursor.setCharFormat(format);//设置光标位置处字符的格式
    cursor.insertText(str);//将改好的格式插入文本
}

### Qt 网络调试助手简介 Qt 是一种跨平台的 C++ 图形用户界面应用程序开发框架,广泛应用于嵌入式系统、桌面应用以及网络通信等领域。对于网络调试助手的实现,主要依赖于 `QtNetwork` 模块中的类,如 `QTcpServer` 和 `QTcpSocket`。 为了构建一个完整的 TCP 调试工具,开发者需要完成以下几个核心功能模块: - **服务端初始化**:通过创建 `QTcpServer` 对象并绑定到指定 IP 地址和端口号来启动监听[^1]。 - **客户端连接管理**:维护已连接客户端列表,并处理新连接事件[^5]。 - **数据收发机制**:支持从任意客户端接收数据并向单个或多个客户端发送消息。 - **异常处理逻辑**:当某个客户端意外断开时能够及时清理资源。 以下是基于上述需求的一个简单示例程序结构: ```cpp #include <QCoreApplication> #include <QTcpServer> #include <QTcpSocket> #include <QDebug> class TcpServer : public QObject { Q_OBJECT public: explicit TcpServer(QObject *parent = nullptr); private slots: void onNewConnection(); void onDataReceived(); private: QTcpServer *server; }; TcpServer::TcpServer(QObject *parent) : QObject(parent), server(new QTcpServer(this)) { connect(server, &QTcpServer::newConnection, this, &TcpServer::onNewConnection); if (!server->listen(QHostAddress::Any, 8080)) qDebug() << "Failed to start server!"; } void TcpServer::onNewConnection(){ QTcpSocket* client = server->nextPendingConnection(); connect(client,&QTcpSocket::readyRead,this,&TcpServer::onDataReceived); } void TcpServer::onDataReceived(){ QTcpSocket* senderClient = qobject_cast<QTcpSocket*>(sender()); QByteArray data = senderClient->readAll(); qDebug() << "Message received:" << data; // Echo back the message as an example. senderClient->write(data); } ``` 此代码片段展示了如何设置基本的服务端架构,其中包括侦听传入请求、读取消息内容并将接收到的信息回显给发送方等功能点。 如果希望获取更详尽的学习材料或者现成项目案例,则可以参考以下链接访问开源仓库下载完整版串口调试辅助软件源码[^4]: [GitHub - confidentFeng/QtAppProject](https://github.com/confidentFeng/QtAppProject/tree/mySerial) 另外值得注意的是,在实际操作过程中可能还会遇到诸如线程同步等问题,因此建议深入研究官方文档及相关书籍进一步提升技能水平[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值