Qt 网络编程 #

网络模块概述 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Qt 网络模块                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  底层网络:                                                  │
│  ├── QTcpSocket      - TCP 客户端                          │
│  ├── QTcpServer      - TCP 服务端                          │
│  └── QUdpSocket      - UDP 通信                            │
│                                                             │
│  高层网络:                                                  │
│  ├── QNetworkAccessManager - HTTP 客户端                   │
│  ├── QNetworkRequest        - 网络请求                     │
│  └── QNetworkReply          - 网络响应                     │
│                                                             │
│  其他:                                                     │
│  ├── QWebSocket      - WebSocket 通信                      │
│  ├── QHostInfo       - 主机信息查询                        │
│  └── QNetworkInterface - 网络接口信息                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

TCP 客户端 #

基本使用 #

cpp
#include <QTcpSocket>

class TcpClient : public QObject
{
    Q_OBJECT
public:
    TcpClient(QObject *parent = nullptr) : QObject(parent)
    {
        socket = new QTcpSocket(this);
        
        connect(socket, &QTcpSocket::connected, this, &TcpClient::onConnected);
        connect(socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
        connect(socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
        connect(socket, &QTcpSocket::errorOccurred, this, &TcpClient::onError);
    }
    
    void connectToServer(const QString &host, quint16 port)
    {
        socket->connectToHost(host, port);
    }
    
    void sendData(const QByteArray &data)
    {
        if (socket->state() == QAbstractSocket::ConnectedState) {
            socket->write(data);
            socket->flush();
        }
    }
    
    void disconnect()
    {
        socket->disconnectFromHost();
    }

private slots:
    void onConnected()
    {
        qDebug() << "Connected to server";
    }
    
    void onDisconnected()
    {
        qDebug() << "Disconnected from server";
    }
    
    void onReadyRead()
    {
        QByteArray data = socket->readAll();
        qDebug() << "Received:" << data;
    }
    
    void onError(QAbstractSocket::SocketError error)
    {
        qDebug() << "Error:" << socket->errorString();
    }

private:
    QTcpSocket *socket;
};

TCP 服务端 #

基本使用 #

cpp
#include <QTcpServer>
#include <QTcpSocket>

class TcpServer : public QObject
{
    Q_OBJECT
public:
    TcpServer(QObject *parent = nullptr) : QObject(parent)
    {
        server = new QTcpServer(this);
        
        connect(server, &QTcpServer::newConnection, this, &TcpServer::onNewConnection);
    }
    
    bool start(quint16 port)
    {
        if (!server->listen(QHostAddress::Any, port)) {
            qDebug() << "Server failed to start:" << server->errorString();
            return false;
        }
        qDebug() << "Server started on port" << port;
        return true;
    }
    
    void stop()
    {
        server->close();
        for (QTcpSocket *client : clients) {
            client->disconnectFromHost();
        }
        clients.clear();
    }

private slots:
    void onNewConnection()
    {
        QTcpSocket *client = server->nextPendingConnection();
        clients.append(client);
        
        connect(client, &QTcpSocket::readyRead, [this, client]() {
            QByteArray data = client->readAll();
            qDebug() << "Received from client:" << data;
            
            // 回显
            client->write("Echo: " + data);
        });
        
        connect(client, &QTcpSocket::disconnected, [this, client]() {
            clients.removeOne(client);
            client->deleteLater();
            qDebug() << "Client disconnected";
        });
    }

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

UDP 通信 #

基本使用 #

cpp
#include <QUdpSocket>

class UdpClient : public QObject
{
    Q_OBJECT
public:
    UdpClient(QObject *parent = nullptr) : QObject(parent)
    {
        socket = new QUdpSocket(this);
        
        connect(socket, &QUdpSocket::readyRead, this, &UdpClient::onReadyRead);
        
        // 绑定端口接收数据
        socket->bind(QHostAddress::Any, 12345);
    }
    
    void sendData(const QString &message, const QString &host, quint16 port)
    {
        QByteArray data = message.toUtf8();
        socket->writeDatagram(data, QHostAddress(host), port);
    }

private slots:
    void onReadyRead()
    {
        while (socket->hasPendingDatagrams()) {
            QByteArray buffer;
            buffer.resize(socket->pendingDatagramSize());
            
            QHostAddress sender;
            quint16 senderPort;
            
            socket->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);
            
            qDebug() << "Received from" << sender.toString() << ":" << senderPort;
            qDebug() << "Data:" << buffer;
        }
    }

private:
    QUdpSocket *socket;
};

HTTP 请求 #

使用 QNetworkAccessManager #

cpp
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

class HttpClient : public QObject
{
    Q_OBJECT
public:
    HttpClient(QObject *parent = nullptr) : QObject(parent)
    {
        manager = new QNetworkAccessManager(this);
    }
    
    void get(const QUrl &url)
    {
        QNetworkRequest request(url);
        QNetworkReply *reply = manager->get(request);
        
        connect(reply, &QNetworkReply::finished, [this, reply]() {
            onFinished(reply);
        });
    }
    
    void post(const QUrl &url, const QByteArray &data)
    {
        QNetworkRequest request(url);
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        
        QNetworkReply *reply = manager->post(request, data);
        
        connect(reply, &QNetworkReply::finished, [this, reply]() {
            onFinished(reply);
        });
    }
    
    void download(const QUrl &url, const QString &savePath)
    {
        QNetworkRequest request(url);
        QNetworkReply *reply = manager->get(request);
        
        QFile *file = new QFile(savePath);
        file->open(QIODevice::WriteOnly);
        
        connect(reply, &QNetworkReply::readyRead, [reply, file]() {
            file->write(reply->readAll());
        });
        
        connect(reply, &QNetworkReply::finished, [reply, file]() {
            file->close();
            file->deleteLater();
            reply->deleteLater();
        });
        
        connect(reply, &QNetworkReply::downloadProgress, 
                [](qint64 received, qint64 total) {
            qDebug() << "Progress:" << received << "/" << total;
        });
    }

private slots:
    void onFinished(QNetworkReply *reply)
    {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray data = reply->readAll();
            qDebug() << "Response:" << data;
        } else {
            qDebug() << "Error:" << reply->errorString();
        }
        reply->deleteLater();
    }

private:
    QNetworkAccessManager *manager;
};

JSON 请求示例 #

cpp
void postJson(const QUrl &url, const QVariantMap &data)
{
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    
    QJsonDocument doc = QJsonDocument::fromVariant(data);
    QByteArray jsonData = doc.toJson();
    
    QNetworkReply *reply = manager->post(request, jsonData);
    
    connect(reply, &QNetworkReply::finished, [reply]() {
        if (reply->error() == QNetworkReply::NoError) {
            QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
            qDebug() << "Response:" << response.toJson();
        }
        reply->deleteLater();
    });
}

主机信息 #

QHostInfo #

cpp
// 查询主机名
QHostInfo::lookupHost("www.qt.io", [](const QHostInfo &info) {
    if (info.error() == QHostInfo::NoError) {
        for (const QHostAddress &address : info.addresses()) {
            qDebug() << "Address:" << address.toString();
        }
    } else {
        qDebug() << "Lookup failed:" << info.errorString();
    }
});

// 获取本机主机名
QString localHostName = QHostInfo::localHostName();

// 从地址获取主机名
QHostInfo info = QHostInfo::fromName("192.168.1.1");
qDebug() << info.hostName();

QNetworkInterface #

cpp
// 获取所有网络接口
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface &interface : interfaces) {
    qDebug() << "Interface:" << interface.name();
    qDebug() << "  Hardware:" << interface.hardwareAddress();
    qDebug() << "  Flags:" << interface.flags();
    
    for (const QNetworkAddressEntry &entry : interface.addressEntries()) {
        qDebug() << "  IP:" << entry.ip().toString();
        qDebug() << "  Netmask:" << entry.netmask().toString();
        qDebug() << "  Broadcast:" << entry.broadcast().toString();
    }
}

// 获取本机 IP 地址
QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
for (const QHostAddress &address : addresses) {
    if (address.protocol() == QAbstractSocket::IPv4Protocol &&
        !address.isLoopback()) {
        qDebug() << "Local IP:" << address.toString();
    }
}

下一步 #

现在你已经掌握了网络编程,接下来学习 数据库操作,了解 Qt 的数据库支持!

最后更新:2026-03-29