天天看点

Qt http操作

在介绍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,这个网站上有些接口亲测可用。

继续阅读