QT实现一个Https客户端

最近在做基于Https协议的项目编程,以下实现一个基于QT的Https的客户端

1.环境

本QT4.7.0+VS2008+Win10.

2.NetWork类库

VS2008中QT project Setting中勾选NetWork library

  1. 三个类

主要使用了以下三个类:
http访问的类:QNetworkAccessManager
http请求的类:QNetworkRequest
http回复的类:QNetworkReply
使用上面三个类可以实现http客户端所有功能,简单地调用如下:

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

QNetworkAccessManager的调用方法,根据不同的类型可以调用不同的方法:

QNetworkReply *	deleteResource ( const QNetworkRequest & request )
QNetworkReply *	get ( const QNetworkRequest & request )
QNetworkReply *	head ( const QNetworkRequest & request )
QNetworkReply *	post ( const QNetworkRequest & request, QIODevice * data )
QNetworkReply *	post ( const QNetworkRequest & request, const QByteArray & data )
QNetworkReply *	put ( const QNetworkRequest & request, QIODevice * data )
QNetworkReply *	put ( const QNetworkRequest & request, const QByteArray & data )


  1. 请求Url和request
	QNetworkRequest request;
    QUrlQuery urlQuery;
    QString urlString;
    QUrl url;
    
    /* url */
    urlString.append("https://httpbin.org/");
    url.setUrl(urlString);

    /* query */
    urlQuery.addQueryItem("id", "123456");
    urlQuery.addQueryItem("time", "2019-10-01 10:30:00");
    url.setQuery(urlQuery);
    //由于QT4.7.0中不支持QUrlQuery类,所以这里可采用手动拼接方式
    if (!url.contains("?", Qt::CaseInsensitive))
     {
		url.append("?");
	} 
	else 
	{
		url.append("&");
	}
	url.append(Key + "=" + Value);

	//拼接最后如下
	https://www.example.com?key1=value1&key2=value2
	
	//也可以使用QUrl的addQueryItem函数
	//QT4的写法:
	QUrl url("http://www.example.com");
	url.addQueryItem("key1", "value1");
	url.addQueryItem("key2", "value2");
	//QT5的写法
	QUrl url("http://www.example.com");
	QUrlQuery urlQuery(url);
	urlQuery.addQueryItem("key1", "value1");
	urlQuery.addQueryItem("key2", "value2");
	url.setQuery(urlQuery);
	//QT4和QT5的混合写法:
	QUrl url("http://www.example.com");
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) // Qt4
    url.addQueryItem("key1", "value1");
    url.addQueryItem("key2", "value2");
#else
    QUrlQuery urlQuery(url);
    urlQuery.addQueryItem("key1", "value1");
    urlQuery.addQueryItem("key2", "value2");
    url.setQuery(urlQuery);
#endif
	

    request.setUrl(url);
  1. 追加或修改头Head数据

    void QNetworkRequest::setRawHeader ( const QByteArray & headerName, const QByteArray & headerValue )

	QNetworkRequest request;
    request.setRawHeader("User-Agent", "QHttpsC 1.0");
    request.setRawHeader("Authorization", "Basic WHtpsWeeSFW4=");
    request.setRawHeader("Last-Modified", "Sun, 06 Nov 2019 08:49:37 GMT");

  1. 增加body数据,使用Post上传负载数据data
	//QNetworkReply *	post ( const QNetworkRequest & request, const QByteArray & data )
	reply = manager->post(request, data);//data数据可能是Json格式串
  1. 返回数据的读取
  • 读取返回的状态码
/*200  服务器成功返回网页 
404  请求的网页不存在 
503  服务不可用*/
	QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    int retCode = statusCode.toInt();
  • 读取返回的头
//QList<QByteArray> QNetworkReply::rawHeaderList () const //取到所有的头的键列表
QList<QByteArray> list = reply->rawHeaderList();
//QByteArray QNetworkReply::rawHeader ( const QByteArray & headerName ) const //通过键名获取对应的值
for (int i = 0; i < list.size(); i++) 
{
		qDebug() << "header: " << list.at(i).data() << " " << reply->rawHeader(list.at(i));
}
  • 接收所有回复的数据
//QByteArray QIODevice::readAll ()
QByteArray  resp = reply->readAll();

3. 支持Https

支持HTTPS请求需要配置OpenSSL环境,Qt默认是不带SSl认证的,直接访问HTTPS会有错误信号。 环境配置:
需要对应的库文件 libeay32.dll和ssleay32.dll。需要下载libeay32.dll 和 ssleay32.dll两个库文件,将这两个库文件拷贝到程序生成目录下(即生成exe的同级目录)或者拷贝到QtNetwork模块的库文件目录中。可以在本地电脑搜索这两个库文件,直接拷贝就行。
Https项目目录文件
并且在发送请求前设置一下:

	QSslConfiguration conf = request.sslConfiguration();
	conf.setPeerVerifyMode(QSslSocket::VerifyNone);
	conf.setProtocol(QSsl::AnyProtocol);
	request.setSslConfiguration(conf);

测试服务器:https://httpbin.org/

4. 请求认证

http请求的认证信息通过增加认证头来实现。用户名和密码常用的加密方式有basic和digest加密
Basic加密头格式:
Authorization: Basic base64(username:password)
Digest加密头格式:
Authorization: Digest MD5(username:realm:password)
这里设计了一个信号槽,如果访问需要认证,将自动调用需要校验的数据,用户名和密码;这里是在发送数据前,需要将认证信息传进去。

/*void QNetworkAccessManager::authenticationRequired ( QNetworkReply * reply, QAuthenticator * authenticator ) [signal]*/

	manager = new QNetworkAccessManager(this);
	connect(manager,SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),this, SLOT(authRequiredReply(QNetworkReply*,QAuthenticator*)));
//实现的槽函数如下
void TestHttpClient::authRequiredReply(QNetworkReply *reply, QAuthenticator *auth)
{
	QString username = ui->username->text();
	QString password = ui->password->text();
	if (username.isEmpty() || password.isEmpty()) {
		return ;
	}
	auth->setUser(username);
	auth->setPassword(password);
}
	
  • 1
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于QT的MQTT服务器和客户可以使用 Eclipse Paho MQTT C++ 客户库来实现。以下是一个简单的示例代码,演示了如何创建一个MQTT服务器和客户: 首先,你需要在QT项目中添加 Eclipse Paho MQTT C++ 客户库。可以通过以下方式将其添加到你的项目中: 1. 下载 Eclipse Paho MQTT C++ 客户库的源代码,可以从官方网站上获取:https://www.eclipse.org/paho/clients/cpp/ 2. 解压下载的源代码文件。 3. 打开你的QT项目,右键点击项目文件,选择 "添加新文件或目录"。 4. 在对话框中,选择 "外部构建"。 5. 在 "目录" 框中选择解压后的源代码文件夹。 6. 点击 "下一步",然后点击 "完成"。 接下来,你可以使用以下示例代码来创建一个MQTT服务器和客户: ```cpp #include <iostream> #include <cstring> #include <mqtt/async_client.h> const std::string SERVER_ADDRESS("tcp://localhost:1883"); const std::string CLIENT_ID("mqtt_client"); const std::string TOPIC("test_topic"); class mqtt_callback : public virtual mqtt::callback { public: void connection_lost(const std::string &cause) override { std::cout << "Connection lost: " << cause << std::endl; } void delivery_complete(mqtt::delivery_token_ptr token) override { std::cout << "Delivery complete" << std::endl; } void message_arrived(const std::string &topic, mqtt::message_ptr msg) override { std::cout << "Message arrived: " << msg->to_string() << std::endl; } }; int main(int argc, char *argv[]) { mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID); mqtt_callback callback; client.set_callback(callback); mqtt::connect_options connOpts; connOpts.set_keep_alive_interval(20); connOpts.set_clean_session(true); try { mqtt::token_ptr conntok = client.connect(connOpts); conntok->wait(); if (!conntok->is_complete()) { std::cerr << "Connection failed: " << conntok->get_reason_code() << std::endl; return 1; } mqtt::token_ptr subtok = client.subscribe(TOPIC, 0); subtok->wait(); if (!subtok->is_complete()) { std::cerr << "Subscribe failed: " << subtok->get_reason_code() << std::endl; return 1; } while (true) { // 发布消息 std::string message; std::getline(std::cin, message); mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, message); pubmsg->set_qos(0); client.publish(pubmsg)->wait(); } mqtt::token_ptr unsubtok = client.unsubscribe(TOPIC); unsubtok->wait(); client.disconnect()->wait(); } catch (const mqtt::exception &exc) { std::cerr << "MQTT exception: " << exc.what() << std::endl; return 1; } return 0; } ``` 这是一个简单的示例,展示了如何使用 Eclipse Paho MQTT C++ 客户库在QT中创建一个MQTT服务器和客户。你可以根据自己的需求进行修改和扩展。记得在编译时链接 Eclipse Paho MQTT C++ 客户库。 希望这可以帮助到你!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼儿LY

一切随缘

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值