• QT TCP服务器和客户端示例程序


    下面是一个简单的 Qt TCP 服务器和客户端示例,演示了如何使用 vSetDrivervSetListenervTcpServerStart 函数。假设 vSetDrivervSetListener 是你定义的自定义函数。

    TCP 服务器部分

    tcpserver.h
    #ifndef TCPSERVER_H
    #define TCPSERVER_H
    
    #include 
    #include 
    
    class TcpServer : public QTcpServer
    {
        Q_OBJECT
    public:
        explicit TcpServer(QObject *parent = nullptr);
        void vSetDriver(QObject *driver);
        void vSetListener(QObject *listener);
        void vTcpServerStart(int port);
    
    signals:
        void log(QString message);
        void connected(quint32 addr, int port);
        void disconnected(quint32 addr, int port);
        void recvData(quint32 addr, int port, QByteArray data);
    
    protected:
        void incomingConnection(qintptr socketDescriptor) override;
    
    private slots:
        void onReadyRead();
        void onDisconnected();
    
    private:
        QObject *m_driver;
        QObject *m_listener;
        QTcpSocket *m_socket;
    };
    
    #endif // TCPSERVER_H
    

    tcpserver.cpp
    #include "tcpserver.h"
    #include 
    
    TcpServer::TcpServer(QObject *parent) : QTcpServer(parent), m_driver(nullptr), m_listener(nullptr), m_socket(nullptr) {}
    
    void TcpServer::vSetDriver(QObject *driver)
    {
        m_driver = driver;
    }
    
    void TcpServer::vSetListener(QObject *listener)
    {
        m_listener = listener;
    }
    
    void TcpServer::vTcpServerStart(int port)
    {
        if (!this->listen(QHostAddress::Any, port)) {
            emit log("Server could not start!");
        } else {
            emit log("Server started!");
        }
    }
    
    void TcpServer::incomingConnection(qintptr socketDescriptor)
    {
        m_socket = new QTcpSocket(this);
        connect(m_socket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);
        connect(m_socket, &QTcpSocket::disconnected, this, &TcpServer::onDisconnected);
    
        m_socket->setSocketDescriptor(socketDescriptor);
        emit connected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
    }
    
    void TcpServer::onReadyRead()
    {
        QByteArray data = m_socket->readAll();
        emit recvData(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort(), data);
    }
    
    void TcpServer::onDisconnected()
    {
        emit disconnected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
        m_socket->deleteLater();
    }
    

    TCP 客户端部分

    tcpclient.h
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H
    
    #include 
    
    class TcpClient : public QObject
    {
        Q_OBJECT
    public:
        explicit TcpClient(QObject *parent = nullptr);
        void connectToServer(const QString &host, int port);
        void sendData(const QByteArray &data);
    
    signals:
        void log(QString message);
        void connected();
        void disconnected();
        void recvData(QByteArray data);
    
    private slots:
        void onReadyRead();
        void onConnected();
        void onDisconnected();
    
    private:
        QTcpSocket *m_socket;
    };
    
    #endif // TCPCLIENT_H
    

    tcpclient.cpp
    #include "tcpclient.h"
    
    TcpClient::TcpClient(QObject *parent) : QObject(parent), m_socket(new QTcpSocket(this))
    {
        connect(m_socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
        connect(m_socket, &QTcpSocket::connected, this, &TcpClient::onConnected);
        connect(m_socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
    }
    
    void TcpClient::connectToServer(const QString &host, int port)
    {
        m_socket->connectToHost(host, port);
    }
    
    void TcpClient::sendData(const QByteArray &data)
    {
        if (m_socket->state() == QAbstractSocket::ConnectedState) {
            m_socket->write(data);
        }
    }
    
    void TcpClient::onReadyRead()
    {
        QByteArray data = m_socket->readAll();
        emit recvData(data);
    }
    
    void TcpClient::onConnected()
    {
        emit log("Connected to server");
        emit connected();
    }
    
    void TcpClient::onDisconnected()
    {
        emit log("Disconnected from server");
        emit disconnected();
    }
    

    示例主程序

    main.cpp
    #include 
    #include "tcpserver.h"
    #include "tcpclient.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        TcpServer server;
        server.vSetDriver(&server);
        server.vSetListener(&server);
        server.vTcpServerStart(12345);
    
        TcpClient client;
        client.connectToServer("127.0.0.1", 12345);
        client.sendData("Hello, Server!");
    
        return a.exec();
    }
    

    main.pro
    QT += core network
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    SOURCES += main.cpp \
               tcpserver.cpp \
               tcpclient.cpp
    
    HEADERS += tcpserver.h \
               tcpclient.h
    

    解释

    • TcpServer 类:
      • vSetDrivervSetListener 方法用于设置驱动和监听对象。
      • vTcpServerStart 方法用于启动服务器。
      • incomingConnection 方法处理新的连接。
      • onReadyReadonDisconnected 方法分别处理数据接收和连接断开事件。
    • TcpClient 类:
      • connectToServer 方法连接到服务器。
      • sendData 方法发送数据。
      • onReadyReadonConnectedonDisconnected 方法分别处理数据接收、连接和断开事件。
    • 主程序
      • 创建并配置服务器和客户端对象。
      • 客户端连接到服务器并发送数据。

    这个示例演示了如何使用 Qt 的网络模块创建一个简单的 TCP 服务器和客户端,并展示了如何通过自定义的 vSetDrivervSetListenervTcpServerStart 方法进行初始化和管理。

    如何测试:

    1. 准备项目结构

    确保项目文件结构正确,并包含以下文件:

    • tcpserver.h
    • tcpserver.cpp
    • tcpclient.h
    • tcpclient.cpp
    • main.cpp
    • myproject.pro

    2. 项目配置文件 (myproject.pro)

    确保你的项目配置文件 (myproject.pro) 正确配置:

    QT += core network
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    SOURCES += main.cpp \
               tcpserver.cpp \
               tcpclient.cpp
    
    HEADERS += tcpserver.h \
               tcpclient.h
    

    3. 编译项目

    使用 qmakemake 编译项目。在终端中执行以下命令:

    qmake myproject.pro
    make
    

    4. 运行测试

    在编译成功后,运行生成的可执行文件。以下是测试步骤:

    4.1 启动服务器

    在一个终端中运行服务器部分:

    ./myproject
    

    此时,服务器应该启动并监听端口 12345,等待客户端连接。

    4.2 启动客户端

    在另一个终端中运行客户端部分:

    ./myproject
    

    此时,客户端应该连接到服务器并发送 “Hello, Server!” 消息。

    5. 验证测试结果

    检查服务器输出

    服务器应该输出类似以下的日志信息:

    Server started!
    connect : 127.0.0.1(12345)
    recv : 127.0.0.1(12345)
    

    检查客户端输出

    客户端应该输出类似以下的日志信息:

    Connected to server
    

    6. 修改和扩展

    根据需要修改和扩展你的代码。例如,你可以在 recvData 信号处理函数中添加更多的处理逻辑,或者在客户端中添加接收服务器响应的功能。

    7. 完整代码示例

    tcpserver.h
    #ifndef TCPSERVER_H
    #define TCPSERVER_H
    
    #include 
    #include 
    
    class TcpServer : public QTcpServer
    {
        Q_OBJECT
    public:
        explicit TcpServer(QObject *parent = nullptr);
        void vSetDriver(QObject *driver);
        void vSetListener(QObject *listener);
        void vTcpServerStart(int port);
    
    signals:
        void log(QString message);
        void connected(quint32 addr, int port);
        void disconnected(quint32 addr, int port);
        void recvData(quint32 addr, int port, QByteArray data);
    
    protected:
        void incomingConnection(qintptr socketDescriptor) override;
    
    private slots:
        void onReadyRead();
        void onDisconnected();
    
    private:
        QObject *m_driver;
        QObject *m_listener;
        QTcpSocket *m_socket;
    };
    
    #endif // TCPSERVER_H
    

    tcpserver.cpp
    #include "tcpserver.h"
    #include 
    
    TcpServer::TcpServer(QObject *parent) : QTcpServer(parent), m_driver(nullptr), m_listener(nullptr), m_socket(nullptr) {}
    
    void TcpServer::vSetDriver(QObject *driver)
    {
        m_driver = driver;
    }
    
    void TcpServer::vSetListener(QObject *listener)
    {
        m_listener = listener;
    }
    
    void TcpServer::vTcpServerStart(int port)
    {
        if (!this->listen(QHostAddress::Any, port)) {
            emit log("Server could not start!");
        } else {
            emit log("Server started!");
        }
    }
    
    void TcpServer::incomingConnection(qintptr socketDescriptor)
    {
        m_socket = new QTcpSocket(this);
        connect(m_socket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);
        connect(m_socket, &QTcpSocket::disconnected, this, &TcpServer::onDisconnected);
    
        m_socket->setSocketDescriptor(socketDescriptor);
        emit connected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
    }
    
    void TcpServer::onReadyRead()
    {
        QByteArray data = m_socket->readAll();
        emit recvData(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort(), data);
    }
    
    void TcpServer::onDisconnected()
    {
        emit disconnected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
        m_socket->deleteLater();
    }
    

    tcpclient.h
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H
    
    #include 
    
    class TcpClient : public QObject
    {
        Q_OBJECT
    public:
        explicit TcpClient(QObject *parent = nullptr);
        void connectToServer(const QString &host, int port);
        void sendData(const QByteArray &data);
    
    signals:
        void log(QString message);
        void connected();
        void disconnected();
        void recvData(QByteArray data);
    
    private slots:
        void onReadyRead();
        void onConnected();
        void onDisconnected();
    
    private:
        QTcpSocket *m_socket;
    };
    
    #endif // TCPCLIENT_H
    

  • 相关阅读:
    MyBatis之SessionFactory与Session简介说明
    spring总结,从底层源码角度概括,一文看懂打通spring任督二脉
    老卫带你学---leetcode刷题(33. 搜索旋转排序数组)
    leetcode-堆
    Java | 类、实例初始化 、方法重写规则
    strings包详细文档+示例
    美团前端一面必会手写面试题汇总
    基于网络爬虫技术的网络新闻分析
    将目录下的所有pdf文件都转换为对应名字的png图片
    Ubuntu16.04无法卸载VSCode
  • 原文地址:https://blog.csdn.net/a15236617777/article/details/139756053