1. Qt6使用tcp协议建立连接后在客户端发送一条文字消息到服务器端而后断开连接。

编写两个使用qt6框架开发的程序一个是服务端一个是客户端,Qt6使用tcp协议建立连接后在客户端发送一条文字消息到服务器端而后断开连接,无ui界面,按照qt风格分开声明与实现,参考qwiget模板但是没有ui。

实现一个最简单的 一次性连接

  • 客户端:启动后连接服务器 → 发送一条文字消息 → 断开连接
  • 服务器:监听端口 → 接收连接 → 读取消息 → 打印到控制台
  • 无 UI,但结构参考 Qt Widget 模板(main.cpp + 一个 QObject 派生类,分头文件和实现文件)
  • Qt6 + CMake,客户端和服务端是两个独立项目

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QTcpSocket *clientSocket;
    };

    #endif // TCPSERVER_H

  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this)),
    clientSocket(nullptr)
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "TCP Server listening on port 8848";
    } else {
    qDebug() << "Failed to start TCP Server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    clientSocket = server->nextPendingConnection();
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QByteArray data = clientSocket->readAll();
    qDebug() << "Received:" << QString::fromUtf8(data);
    }

    void TcpServer::onClientDisconnected()
    {
    qDebug() << "Client disconnected";
    clientSocket->deleteLater();
    clientSocket = nullptr;
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }

  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();

    private:
    QTcpSocket *socket;
    };

    #endif // TCPCLIENT_H

  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";
    QByteArray message = "Hello from TCP client!";
    socket->write(message);
    socket->flush();
    socket->disconnectFromHost();
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2. Qt6使用tcp协议建立连接后在客户端发送多条文字消息到服务器端。

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QList<QTcpSocket*> clients;
    };

    #endif // TCPSERVER_H

  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this))
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "TCP Server listening on port 8848";
    } else {
    qDebug() << "Failed to start TCP Server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    QTcpSocket *clientSocket = server->nextPendingConnection();
    clients << clientSocket;
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QTcpSocket *senderSocket = qobject_cast<QTcpSocket*>(sender());
    if (!senderSocket) return;

    QByteArray data = senderSocket->readAll();
    qDebug() << "Received:" << QString::fromUtf8(data).trimmed();
    }

    void TcpServer::onClientDisconnected()
    {
    QTcpSocket *senderSocket = qobject_cast<QTcpSocket*>(sender());
    if (!senderSocket) return;

    qDebug() << "Client disconnected";
    clients.removeAll(senderSocket);
    senderSocket->deleteLater();
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }

  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>
    #include <QTimer>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void sendMessage();
    void onDisconnected();

    private:
    QTcpSocket *socket;
    QTimer timer;
    int messageCount;
    };

    #endif // TCPCLIENT_H

  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this)),
    messageCount(0)
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);

    connect(&timer, &QTimer::timeout,
    this, &TcpClient::sendMessage);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";
    timer.start(1000); // 每秒发送一次
    }

    void TcpClient::sendMessage()
    {
    if (messageCount >= 5) {
    timer.stop();
    socket->disconnectFromHost();
    return;
    }

    QString msg = QString("Message %1 from client").arg(messageCount + 1);
    socket->write(msg.toUtf8());
    socket->flush();
    qDebug() << "Sent:" << msg;
    messageCount++;
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

3. Qt6使用tcp协议建立连接后在服务端发送一条文字消息到客户端。

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QTcpSocket *clientSocket;
    };

    #endif // TCPSERVER_H

  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this)),
    clientSocket(nullptr)
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "TCP Server listening on port 8848";
    } else {
    qDebug() << "Failed to start TCP Server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    clientSocket = server->nextPendingConnection();
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);

    // 主动发送一条消息
    QByteArray message = "Hello from TCP server!";
    clientSocket->write(message);
    clientSocket->flush();
    }

    void TcpServer::onClientDisconnected()
    {
    qDebug() << "Client disconnected";
    clientSocket->deleteLater();
    clientSocket = nullptr;
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }

  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onReadyRead();
    void onDisconnected();

    private:
    QTcpSocket *socket;
    };

    #endif // TCPCLIENT_H

  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::readyRead,
    this, &TcpClient::onReadyRead);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";
    }

    void TcpClient::onReadyRead()
    {
    QByteArray data = socket->readAll();
    qDebug() << "Received from server:" << QString::fromUtf8(data).trimmed();
    socket->disconnectFromHost();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

4. Qt6使用tcp协议建立连接后在客户端发送消息到服务器后,服务器返回消息。

升级这个 Qt6 TCP 通信模型,实现:

✅ 客户端连接后发送一条消息到服务器
✅ 服务器接收后,返回一条响应消息给客户端
✅ 客户端打印收到的服务器响应

🧠 通信流程概览

[Client] → “Hello Server!” → [Server]
[Server] → “Hello Client!” → [Client]

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QTcpSocket *clientSocket;
    };

    #endif // TCPSERVER_H
  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this)),
    clientSocket(nullptr)
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "Server listening on port 8848";
    } else {
    qDebug() << "Failed to start server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    clientSocket = server->nextPendingConnection();
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QByteArray data = clientSocket->readAll();
    qDebug() << "Received from client:" << QString::fromUtf8(data).trimmed();

    // 回复客户端
    QByteArray reply = "Hello Client!";
    clientSocket->write(reply);
    clientSocket->flush();
    }

    void TcpServer::onClientDisconnected()
    {
    qDebug() << "Client disconnected";
    clientSocket->deleteLater();
    clientSocket = nullptr;
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }

  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onReadyRead();
    void onDisconnected();

    private:
    QTcpSocket *socket;
    };

    #endif // TCPCLIENT_H
  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::readyRead,
    this, &TcpClient::onReadyRead);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";

    // 发送消息给服务端
    QByteArray message = "Hello Server!";
    socket->write(message);
    socket->flush();
    }

    void TcpClient::onReadyRead()
    {
    QByteArray data = socket->readAll();
    qDebug() << "Received from server:" << QString::fromUtf8(data).trimmed();
    socket->disconnectFromHost();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

5.Qt6使用tcp协议建立连接后在客户端与服务器端之间互相发送文本消息。

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QTimer>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();
    void sendMessageToClient();

    private:
    QTcpServer *server;
    QTcpSocket *clientSocket;
    QTimer sendTimer;
    };

    #endif // TCPSERVER_H
  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this)),
    clientSocket(nullptr)
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "Server listening on port 8848";
    } else {
    qDebug() << "Failed to start server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);

    // 定时器模拟服务器主动发消息
    sendTimer.setInterval(3000); // 每3秒发一次
    connect(&sendTimer, &QTimer::timeout,
    this, &TcpServer::sendMessageToClient);
    }

    void TcpServer::onNewConnection()
    {
    clientSocket = server->nextPendingConnection();
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);

    sendTimer.start();
    }

    void TcpServer::onReadyRead()
    {
    QByteArray data = clientSocket->readAll();
    qDebug() << "Server received:" << QString::fromUtf8(data).trimmed();

    // 回复客户端
    QByteArray reply = "Server echo: " + data;
    clientSocket->write(reply);
    clientSocket->flush();
    }

    void TcpServer::onClientDisconnected()
    {
    qDebug() << "Client disconnected";
    sendTimer.stop();
    clientSocket->deleteLater();
    clientSocket = nullptr;
    }

    void TcpServer::sendMessageToClient()
    {
    if (clientSocket && clientSocket->state() == QAbstractSocket::ConnectedState) {
    QByteArray msg = "Server periodic message";
    clientSocket->write(msg);
    clientSocket->flush();
    qDebug() << "Server sent periodic message";
    }
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }
  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>
    #include <QTimer>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onReadyRead();
    void onDisconnected();
    void sendMessageToServer();

    private:
    QTcpSocket *socket;
    QTimer sendTimer;
    };

    #endif // TCPCLIENT_H
  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::readyRead,
    this, &TcpClient::onReadyRead);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);

    // 定时器模拟客户端主动发消息
    sendTimer.setInterval(5000); // 每5秒发一次
    connect(&sendTimer, &QTimer::timeout,
    this, &TcpClient::sendMessageToServer);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";

    // 连接成功后先发一条
    QByteArray message = "Hello Server!";
    socket->write(message);
    socket->flush();

    sendTimer.start();
    }

    void TcpClient::onReadyRead()
    {
    QByteArray data = socket->readAll();
    qDebug() << "Client received:" << QString::fromUtf8(data).trimmed();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    sendTimer.stop();
    }

    void TcpClient::sendMessageToServer()
    {
    if (socket->state() == QAbstractSocket::ConnectedState) {
    QByteArray msg = "Client periodic message";
    socket->write(msg);
    socket->flush();
    qDebug() << "Client sent periodic message";
    }
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

    🔍 运行效果

    服务端输出:

    1
    2
    3
    4
    5
    6
    Server listening on port 8848
    Client connected from "127.0.0.1"
    Server received: "Hello Server!"
    Server sent periodic message
    Server received: "Client periodic message"
    ...

    客户端输出:

    1
    2
    3
    4
    5
    6
    7
    Connecting to "127.0.0.1" : 8848
    Connected to server
    Client received: "Server echo: Hello Server!"
    Client received: "Server periodic message"
    Client sent periodic message
    Client received: "Server echo: Client periodic message"
    ...

6.Qt6使用tcp协议建立连接后使用服务器转发客户端的消息到其他客户端

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }

  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QList>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QList<QTcpSocket*> clients;

    void broadcastMessage(QTcpSocket *sender, const QByteArray &message);
    };

    #endif // TCPSERVER_H

  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this))
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "Server listening on port 8848";
    } else {
    qDebug() << "Failed to start server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    QTcpSocket *clientSocket = server->nextPendingConnection();
    clients.append(clientSocket);

    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QTcpSocket *senderSocket = qobject_cast<QTcpSocket*>(sender());
    if (!senderSocket) return;

    QByteArray data = senderSocket->readAll();
    qDebug() << "Received from client:" << QString::fromUtf8(data).trimmed();

    // 转发给其他客户端
    broadcastMessage(senderSocket, data);
    }

    void TcpServer::onClientDisconnected()
    {
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket) return;

    qDebug() << "Client disconnected";
    clients.removeAll(clientSocket);
    clientSocket->deleteLater();
    }

    void TcpServer::broadcastMessage(QTcpSocket *sender, const QByteArray &message)
    {
    for (QTcpSocket *client : clients) {
    if (client != sender && client->state() == QAbstractSocket::ConnectedState) {
    client->write(message);
    client->flush();
    }
    }
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("127.0.0.1", 8848);
    return a.exec();
    }

  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>
    #include <QTimer>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onReadyRead();
    void onDisconnected();
    void sendMessage();

    private:
    QTcpSocket *socket;
    QTimer sendTimer;
    int counter = 0;
    };

    #endif // TCPCLIENT_H

  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::readyRead,
    this, &TcpClient::onReadyRead);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);

    sendTimer.setInterval(4000); // 每4秒发一次
    connect(&sendTimer, &QTimer::timeout,
    this, &TcpClient::sendMessage);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";
    sendTimer.start();
    }

    void TcpClient::onReadyRead()
    {
    QByteArray data = socket->readAll();
    qDebug() << "Client received:" << QString::fromUtf8(data).trimmed();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    sendTimer.stop();
    }

    void TcpClient::sendMessage()
    {
    if (socket->state() == QAbstractSocket::ConnectedState) {
    QByteArray msg = QString("Message %1 from client").arg(++counter).toUtf8();
    socket->write(msg);
    socket->flush();
    qDebug() << "Client sent:" << msg;
    }
    }

  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

7.Qt6使用tcp协议建立连接后在多客户端转发服务器基础上,加上昵称统一的消息格式

设计思路

  1. 客户端启动时先发送一条特殊的“昵称注册”消息给服务器(例如 NICK:qi)。

  2. 服务器保存每个 QTcpSocket 对应的昵称。

  3. 普通聊天消息统一格式为:

  4. [昵称] 消息内容

  5. 服务器转发时,自动加上发送者昵称。

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }
  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QMap>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QMap<QTcpSocket*, QString> clients; // 保存socket和昵称映射

    void broadcastMessage(QTcpSocket *sender, const QString &message);
    };

    #endif // TCPSERVER_H
  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this))
    {
    if (server->listen(QHostAddress::Any, 8848)) {
    qDebug() << "Server listening on port 8848";
    } else {
    qDebug() << "Failed to start server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    QTcpSocket *clientSocket = server->nextPendingConnection();
    clients[clientSocket] = ""; // 初始无昵称

    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QTcpSocket *senderSocket = qobject_cast<QTcpSocket*>(sender());
    if (!senderSocket) return;

    QByteArray rawData = senderSocket->readAll();
    QString text = QString::fromUtf8(rawData).trimmed();

    // 如果是昵称注册
    if (text.startsWith("NICK:")) {
    QString nick = text.mid(5).trimmed();
    clients[senderSocket] = nick;
    qDebug() << "Client set nickname:" << nick;
    return;
    }

    QString senderNick = clients.value(senderSocket, "Unknown");
    QString formatted = QString("[%1] %2").arg(senderNick, text);

    qDebug() << "Broadcast:" << formatted;
    broadcastMessage(senderSocket, formatted);
    }

    void TcpServer::onClientDisconnected()
    {
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket) return;

    QString nick = clients.value(clientSocket, "Unknown");
    qDebug() << nick << "disconnected";

    clients.remove(clientSocket);
    clientSocket->deleteLater();
    }

    void TcpServer::broadcastMessage(QTcpSocket *sender, const QString &message)
    {
    for (QTcpSocket *client : clients.keys()) {
    if (client != sender && client->state() == QAbstractSocket::ConnectedState) {
    client->write(message.toUtf8());
    client->flush();
    }
    }
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client("qi"); // 这里设置昵称
    client.start("127.0.0.1", 8848);
    return a.exec();
    }
  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>
    #include <QTimer>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(const QString &nickname, QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onReadyRead();
    void onDisconnected();
    void sendMessage();

    private:
    QTcpSocket *socket;
    QTimer sendTimer;
    QString nick;
    int counter = 0;
    };

    #endif // TCPCLIENT_H
  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(const QString &nickname, QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this)),
    nick(nickname)
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::readyRead,
    this, &TcpClient::onReadyRead);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);

    sendTimer.setInterval(4000);
    connect(&sendTimer, &QTimer::timeout,
    this, &TcpClient::sendMessage);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";

    // 先发送昵称注册
    socket->write(QString("NICK:%1").arg(nick).toUtf8());
    socket->flush();

    sendTimer.start();
    }

    void TcpClient::onReadyRead()
    {
    QByteArray data = socket->readAll();
    qDebug() << "Client received:" << QString::fromUtf8(data).trimmed();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    sendTimer.stop();
    }

    void TcpClient::sendMessage()
    {
    if (socket->state() == QAbstractSocket::ConnectedState) {
    QByteArray msg = QString("Hello from %1 (%2)")
    .arg(nick)
    .arg(++counter)
    .toUtf8();
    socket->write(msg);
    socket->flush();
    qDebug() << "Client sent:" << msg;
    }
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

8.Qt6使用tcp协议建立连接后与ipv6地址在客户端发送一条文字消息到服务器端。

1.tcpserver

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <QCoreApplication>
    #include "tcpserver.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpServer server;
    return a.exec();
    }
  2. tcpserver.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QTcpServer>
    #include <QTcpSocket>

    class TcpServer : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpServer(QObject *parent = nullptr);

    private slots:
    void onNewConnection();
    void onReadyRead();
    void onClientDisconnected();

    private:
    QTcpServer *server;
    QTcpSocket *clientSocket;
    };

    #endif // TCPSERVER_H
  3. tcpserver.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include "tcpserver.h"
    #include <QDebug>

    TcpServer::TcpServer(QObject *parent)
    : QObject(parent),
    server(new QTcpServer(this)),
    clientSocket(nullptr)
    {
    // 绑定到 IPv6 任意地址
    if (server->listen(QHostAddress::AnyIPv6, 8848)) {
    qDebug() << "TCP IPv6 Server listening on port 8848";
    } else {
    qDebug() << "Failed to start TCP IPv6 Server";
    }

    connect(server, &QTcpServer::newConnection,
    this, &TcpServer::onNewConnection);
    }

    void TcpServer::onNewConnection()
    {
    clientSocket = server->nextPendingConnection();
    qDebug() << "Client connected from" << clientSocket->peerAddress().toString();

    connect(clientSocket, &QTcpSocket::readyRead,
    this, &TcpServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected,
    this, &TcpServer::onClientDisconnected);
    }

    void TcpServer::onReadyRead()
    {
    QByteArray data = clientSocket->readAll();
    qDebug() << "Received from client:" << QString::fromUtf8(data).trimmed();
    }

    void TcpServer::onClientDisconnected()
    {
    qDebug() << "Client disconnected";
    clientSocket->deleteLater();
    clientSocket = nullptr;
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpserver LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpserver
    main.cpp
    tcpserver.h tcpserver.cpp
    )
    target_link_libraries(tcpserver Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpserver
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )

2.tcpclient

  1. main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <QCoreApplication>
    #include "tcpclient.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TcpClient client;
    client.start("::1", 8848); // IPv6 回环地址
    return a.exec();
    }
  2. tcpclient.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H

    #include <QObject>
    #include <QTcpSocket>

    class TcpClient : public QObject
    {
    Q_OBJECT
    public:
    explicit TcpClient(QObject *parent = nullptr);
    void start(const QString &host, quint16 port);

    private slots:
    void onConnected();
    void onDisconnected();

    private:
    QTcpSocket *socket;
    };

    #endif // TCPCLIENT_H
  3. tcpclient.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include "tcpclient.h"
    #include <QDebug>

    TcpClient::TcpClient(QObject *parent)
    : QObject(parent),
    socket(new QTcpSocket(this))
    {
    connect(socket, &QTcpSocket::connected,
    this, &TcpClient::onConnected);
    connect(socket, &QTcpSocket::disconnected,
    this, &TcpClient::onDisconnected);
    }

    void TcpClient::start(const QString &host, quint16 port)
    {
    qDebug() << "Connecting to" << host << ":" << port;
    socket->connectToHost(host, port, QIODevice::WriteOnly, QAbstractSocket::IPv6Protocol);
    }

    void TcpClient::onConnected()
    {
    qDebug() << "Connected to server";
    QByteArray message = "Hello from IPv6 TCP client!";
    socket->write(message);
    socket->flush();
    socket->disconnectFromHost();
    }

    void TcpClient::onDisconnected()
    {
    qDebug() << "Disconnected from server";
    }
  4. CmakeList.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    cmake_minimum_required(VERSION 3.16)

    project(tcpclient LANGUAGES CXX)

    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core NetWork)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core NetWork)

    add_executable(tcpclient
    main.cpp
    tcpclient.h tcpclient.cpp
    )
    target_link_libraries(tcpclient Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Network)

    include(GNUInstallDirs)
    install(TARGETS tcpclient
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )