Qt项目实战4:http客户端工具

项目概述

本篇项目主要是通过QT的网络API接口实现一个http客户端的工具qhttpc。
qhttpc工具,支持http协议,实现了http的数据请求和回复数据解析。暂不支持https,可自行配置。
工具的源码链接: github/qhttpc

qhttpc功能实现

  • 支持通过URL访问http服务器
  • 支持选择GET、POST、PUT、DELETE、HEAD等请求方式
  • 支持在URL后追加query字段
  • 支持追加PUT/POST body数据
  • 支持显示接收回复body数据
  • 支持显示接收回复头数据

QNetwork类

在.pro文件中增加网络组件支持

QT += network

http访问的类:QNetworkAccessManager
http请求的类:QNetworkRequest
http回复的类:QNetworkReply

使用上述三个类即可实现所有的http客户端的功能,用法可以简单概括为:

reply = manager->get(request);
reply = manager->post(request, data);

http请求

(1)选择请求method
使用QNetwofkAccessManager类发起请求,最终调用方法根据请求的method选择,有以下几种:

    QNetworkReply *head(const QNetworkRequest &request);
    QNetworkReply *get(const QNetworkRequest &request);
    QNetworkReply *post(const QNetworkRequest &request, QIODevice *data);
    QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data);
    QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart);
    QNetworkReply *put(const QNetworkRequest &request, QIODevice *data);
    QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data);
    QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart);
    QNetworkReply *deleteResource(const QNetworkRequest &request);
    QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = Q_NULLPTR);

(2)构造请求uri和query

    QNetworkRequest request;
    QUrlQuery urlQuery;
    QString urlString;
    QUrl url;

    /* url */
    urlString.append("http://");
    urlString.append("www.baidu.com");
    urlString.append("/echo");
    url.setUrl(urlString);

    /* query */
    urlQuery.addQueryItem("id", "123456");
    urlQuery.addQueryItem("time", "2019-01-01 10:30:00");
    url.setQuery(urlQuery);

    request.setUrl(url);

(3)追加/修改请求头

    QNetworkRequest request;

    request.setRawHeader("User-Agent", "qhttpc 1.0");
    request.setRawHeader("Authorization", "Basic YWRtaW46YWRtaW4=");

(3)追加请求body
在使用post或put方式的请求时,需要追加请求负载数据时,将负载数据带入请求

	manager->post(request, data);

http回复

(1)接收回复状态码

	QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (statusCode.isValid()) {
        qDebug() << "recv finished: " << statusCode.toInt();
    }

    int httpCode = statusCode.toInt();

(2)接收回复头

	QList<QByteArray> list = reply->rawHeaderList();
    for (int i = 0; i < list.size(); i++) {
        qDebug() << "header: " << list.at(i).data() << " " << reply->rawHeader(list.at(i));
    }

(3)接收回复数据

	response = reply->readAll();

http同步接收数据

增加定时器,设置超时时间为30秒,当reply接收完成或超时后,eventLoop.exec()执行退出,继续处理数据处理操作

    QEventLoop eventLoop;
    QTimer timer;

    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
    timer.start(30 * 1000);
    eventLoop.exec(); // block until finish

    if (timer.isActive()) {
        timer.stop();
    } else {
        disconnect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
        reply->abort();
        reply->deleteLater();
        return -1;
    }

http用户认证

http请求的认证信息通过增加认证头来实现。用户名和密码常用的加密方式有basic和digest加密

Basic加密头格式:

Authorization: Basic base64(username:password)

Digest加密头格式:

Authorization: Digest MD5(username:realm:password)

如果认证方式选择Basic方式,并且输入了用户名和密码,工具中实现将追加Authorization,尝试发起附带认证头的请求。无法追加Digest认证头,是因为需要根据服务端返回的数据对用户名和密码进行加密。

Qt中将用户认证的过程封装在内部实现,在需要认证时只需输入用户名和密码,QNetworkAccessManager类会自动生成认证头。使用方式如下:

通过QNetworkAccessManager类设置认证请求的槽函数,在槽函数中将用户的认证信息设置生效

    connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
                this, SLOT(authRequiredReply(QNetworkReply*,QAuthenticator*)));

当服务端返回了401的错误码后,会触发authenticationRequire信号,信号处理函数如下所示:

void Widget::authRequiredReply(QNetworkReply *reply, QAuthenticator *auth)
{
    QString username = ui->usernameLineEdit->text();
    QString password = ui->passwordLineEdit->text();

    qDebug() << "username: " << username << "password: " << password;
    if (username.isEmpty() || password.isEmpty()) {
        QMessageBox::information(this, tr("Error"), tr("Please input valid username and passowrd!"));
        return ;
    }

    auth->setUser(username);
    auth->setPassword(password);
}

界面设计

主界面主要包含三部分:URL组件、request信息组件、reply信息显示组件
ui
当输入了有效的URL后,点击发送,会自动发起http请求。可以通过Method的combox框选择请求方式;需要在URL后追加query信息是,在发送tab的Query界面进行key和value的追加;需要发起PUT或POST请求时,通过发送tab的Body界面输入需要追加的请求数据。
如果服务端成功返回了数据,返回头显示在是接收tab的Headers界面,返回body显示在是接收tab的Body界面。

工具的界面所对应的http协议如下所示:
在这里插入图片描述

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值