在介绍Qt http之前,先介绍以下http的基本过程:http是一个简单的请求-响应协议,百度上是这么定义的:http通常运行在TCP之上,它是基于C/S架构进行通信的,其客户端的实现程序主要是Web浏览器,例如Firefox、InternetExplorer等。Web服务是基于TCP的,因此为了能够随时响应客户端的请求,Web服务器需要监听在80/TCP端口。这客户端浏览器和Web服务器之间就可以通过HTTP协议进行通信了。
http通信过程包括:客户与服务器建立连接;客户向服务器提出请求;服务器接受请求,并根据请求返回相应的文件作为应答;客户与服务器关闭连接。HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符。我们可以这样认为: 一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的 查,改,增,删 4个操作。这里客户端可以理解为浏览器,简单来说,http通过url解析得到服务器地址和端口,通过post或者get向url发出请求,服务器根据请求做相应的处理,并且返回给客户端消息表示成功收到,其中post一般来说是用来向服务器提交数据,比如完成表单数据的提交,将数据提交给服务器处理,get仅仅是获取资源信息,就像数据库查询一样,不会修改和增加数据,不会影响资源的状态。当然这不是一定的,因为修改与否是由服务端决定的。
Qt提供了QNetworkRequest,QNetworkAccessManager和QNetworkReply三个类完成http客户端的操作,注意Qt本身没有提供http服务端程序,但是有些开源的http Qt服务端库,如QDjango,是模仿python Django写的,当然没有Django功能丰富,至少收文件这块我没发现。
好吧,现在正式开始.首先,我们要建立一个服务端,这个服务端主要完成http数据的接收和反馈,为了方便,这里使用python flask框架建立http服务端。
# -*- coding: utf-8 -*-
from flask import Flask,request
app=Flask(__name__);
@app.route("/getRes",methods=['GET','POST'])
def getRes():
name=request.form['name'];
nodeNm=request.form['nodeNm'];
print([name,nodeNm]);
return "success";
if __name__ == '__main__':
app.run(host='127.0.0.1',port=5000);
在这里,我们建立了一个http服务器,并运行,地址为http://127.0.0.1/5000/getRes,传参数key值为name和nodeNm,如果成功返回客户端一个success。
下面我们用qt http向服务器发送数据:
class Send::public QObject
{
Q_OBJECT
public:
Send()
{
QNetworkAccessManager *accessManager = new QNetworkAccessManager;
QNetworkRequest request;
request.setUrl(QUrl("http://127.0.0.1:5000/getRes"));
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
QByteArray postData;
postData.append("name=ems&nodeNm=3000");//准备数据name和nodeNm
connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishSlot(QNetworkReply*)));
QNetworkReply *reply=accessManager->post(request,postData);//向指定服务端发送数据
}
public slots:
finishSlot(QNetworkReply *reply) //接收服务端反馈数据
{
qDebug()<<reply->readAll();
}
};
运行之后,我们就可以在qt客户端答应出success;注意,Qt的http是异步的,因此不要指望在post返回值处获得值。
另外,Qt 可以通过get去获取服务器上的值,当然这个值也需要服务器指定,现在修改flask http服务端
# -*- coding: utf-8 -*-
from flask import Flask,request
app=Flask(__name__);
@app.route("/getRes",methods=['GET','POST'])
def getRes():
if(request.method=="POST"):
name=request.form['name'];
nodeNm=request.form['nodeNm'];
print([name,nodeNm]);
return "success";
elif(request.method=="GET"):
return "we need get val";
if __name__ == '__main__':
app.run(host='127.0.0.1',port=5000);
这里顺带flask的一个小问题,flask 中在外部不能定义全局变量,进去也当局部变量了,网上说只能将参数存入数据库或者文件,所有get这儿我没有返回name和nodeNm的值;
言归正传,下面看怎么使用Qt http的get:
class Receive:public QObeject
{
Q_OBJECT
public:
Receive()
{
request= new QNetworkRequest();
request->setUrl(QUrl("http://127.0.0.1:5000/getRes"));
request->setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form- urlencoded");
m_accessManager=new QNetworkAccessManager;
reply=m_accessManager->get(*request);
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
}
public slots:
slotReadyRead()
{
qDebug()<<reply->readAll();
}
};
运行之后,我们就会返回“we need get val"
Qt 中http严格执行了http的规范,即在客户端get只能获取数据,post提交数据。但是从服务端可以看出,get,post其实可以执行相同的操作,因此Qt阉割了get参数选项,当然这也造成了获取数据部分不方便,如我们仅想要得到参数name的值。实际上,在其他一些http框架中,get/post很容易混同。put类似。
另外,网上也有一些免费开放的http接口,可以用于测试,不用搭建服务器:https://www.jianshu.com/p/36eb532d06da,这个网站上有些接口亲测可用。