QT中的TCP

在 Qt 中实现 TCP 通信,可以使用 `QTcpSocket` 来创建客户端,使用 `QTcpServer` 来创建服务器端。服务器端可以接受多个客户端连接,通常是通过创建多个 `QTcpSocket` 对象来管理每一个客户端连接。

### 1. **TCP 服务器端**

服务器端的主要工作是监听某个端口,等待客户端连接。每当有一个新的客户端连接时,服务器会创建一个新的 `QTcpSocket` 对象来与客户端通信。

#### 服务器端代码:

```cpp
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
#include <QDebug>

class TcpServer : public QTcpServer
{
    Q_OBJECT

public:
    TcpServer(QObject *parent = nullptr) : QTcpServer(parent) {}

protected:
    void incomingConnection(qintptr socketDescriptor) override
    {
        // 创建一个新的 QTcpSocket 对象来处理这个连接
        QTcpSocket *clientSocket = new QTcpSocket(this);

        // 将客户端连接与 socketDescriptor 关联
        if (!clientSocket->setSocketDescriptor(socketDescriptor)) {
            qDebug() << "Error: " << clientSocket->errorString();
            delete clientSocket;
            return;
        }

        // 连接客户端的信号槽
        connect(clientSocket, &QTcpSocket::readyRead, this, &TcpServer::readClientData);
        connect(clientSocket, &QTcpSocket::disconnected, this, &TcpServer::clientDisconnected);

        qDebug() << "New client connected!";
    }

private slots:
    void readClientData()
    {
        QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
        if (clientSocket) {
            QByteArray data = clientSocket->readAll();
            qDebug() << "Received from client: " << data;

            // 回送数据到客户端
            clientSocket->write("Hello from server!");
        }
    }

    void clientDisconnected()
    {
        QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
        if (clientSocket) {
            qDebug() << "Client disconnected.";
            clientSocket->deleteLater();
        }
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TcpServer server;
    if (!server.listen(QHostAddress::Any, 1234)) {
        qDebug() << "Server could not start!";
        return -1;
    }

    qDebug() << "Server started, waiting for clients...";

    return a.exec();
}

#include "main.moc"
```

### 代码说明:
1. **`QTcpServer`**:负责监听端口并接受客户端连接。
2. **`incomingConnection()`**:每当有客户端连接时,这个函数会被调用。它会为每个客户端创建一个新的 `QTcpSocket` 对象,用于与客户端通信。
3. **`QTcpSocket`**:用于与客户端进行通信。
4. **`readyRead`** 信号:当数据可读取时触发,调用 `readClientData()` 来读取数据。
5. **`disconnected`** 信号:当客户端断开连接时触发,调用 `clientDisconnected()` 来清理资源。

### 2. **TCP 客户端**

客户端负责连接到服务器并发送数据。

#### 客户端代码:

```cpp
#include <QTcpSocket>
#include <QCoreApplication>
#include <QDebug>

class TcpClient : public QObject
{
    Q_OBJECT

public:
    TcpClient(QObject *parent = nullptr) : QObject(parent)
    {
        socket = new QTcpSocket(this);

        // 连接到服务器
        socket->connectToHost("127.0.0.1", 1234);
        connect(socket, &QTcpSocket::connected, this, &TcpClient::onConnected);
        connect(socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
        connect(socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
    }

private slots:
    void onConnected()
    {
        qDebug() << "Connected to server!";
        socket->write("Hello, server!");
    }

    void onReadyRead()
    {
        QByteArray data = socket->readAll();
        qDebug() << "Received from server: " << data;
    }

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

private:
    QTcpSocket *socket;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TcpClient client;

    return a.exec();
}

#include "main.moc"
```

### 代码说明:
1. **`QTcpSocket`**:用于与服务器通信。
2. **`connectToHost()`**:连接到指定的 IP 地址和端口号。
3. **`connected`** 信号:当连接成功时触发,客户端会发送数据给服务器。
4. **`readyRead`** 信号:当有数据从服务器接收时触发,读取并输出数据。
5. **`disconnected`** 信号:当与服务器的连接断开时触发。

### 3. **多个客户端支持**

服务器端通过 `QTcpServer` 的 `incomingConnection()` 函数接收到每一个新的客户端连接,并为每个连接创建独立的 `QTcpSocket`。因此,服务器端能够同时与多个客户端进行通信。每个客户端都有一个独立的 `QTcpSocket`,它负责与对应的客户端进行数据交换。

### 4. **测试**
- 先启动服务器。
- 然后启动多个客户端实例,它们都会尝试连接到服务器。
- 每个客户端与服务器建立连接后,可以互相发送数据。

这样就实现了一个支持多个客户端连接的 TCP 服务器和客户端通信的基本框架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值