网络通信

到目前为止,C++的标准库仍然没有网络功能,代码中如果需要使用Socket套接字需要借助Windows或Posix系统API,如果想使用HTTP、FTP等应用层协议,就不得不引入第三方库了。Qt中对应用开发中各种常用的网络功能做了一个跨平台的封装,使用十分简便。

链接Network模块

在CMakeLists.txt中我们需要添加如下配置,在构建时链接Qt的Network库。

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network)
target_link_libraries(hello PRIVATE Qt${QT_VERSION_MAJOR}::Network)

获取网络相关信息

网络相关应用中,经常需要获取IP、主机名等信息,这些信息可以通过Qt封装的QHostInfoQNetworkInterface等接口获取。下面例子中,我们输出了主机名和当前计算机的网络接口。

// 主机名
QString hostName = QHostInfo::localHostName();
qDebug() << hostName;

// 网络接口
QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
qDebug() << interfaceList;

使用HTTP协议

现在绝大多数的互联网应用,除非有特殊要求,一般都是通过HTTP协议进行通信的。下面例子中,我们通过HTTP协议的GET方式请求服务端的数据。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTextStream>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();
    void handleHttpReply(QNetworkReply *reply);

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager *manager;
};
#endif // MAINWINDOW_H

上面代码中,槽函数handleHttpReply()用于响应HTTP请求完成的信号。

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);
    connect(manager, &QNetworkAccessManager::finished, this, &MainWindow::handleHttpReply);
}

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

void MainWindow::on_pushButton_clicked()
{
    QString urlStr =  ui->lineEdit->text();
    if (!urlStr.isEmpty())
    {
        QUrl url = QUrl(urlStr);
        if (url.isValid())
        {
            QNetworkRequest req = QNetworkRequest(url);
            manager->get(req);
        }
    }
}

void MainWindow::handleHttpReply(QNetworkReply *reply)
{
    QTextStream in(reply);
    in.setCodec("UTF-8");
    QString replyStr = in.readAll();
    ui->plainTextEdit->setPlainText(replyStr);
}

我们在构造函数中,初始化了QNetWorkAccessManager对象,然后绑定其finished信号到我们的处理槽函数handleHttpReply()。按钮点击时,将用户输入的URL转化为QNetworkRequest请求对象,然后调用manager->get()方法发出HTTP请求。

请求完成后,我们将返回的响应体读入plainTextEdit,这里因为QNetworkReply本身继承于QIODevice,因此我们通过文本流QTextStream读取即可。

当然上述代码比较简陋,HTTP协议本身还是很复杂的,具体使用时参考文档即可。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap