网络通信中最常用的协议就是http协议,Qt对http协议的调用进行了封装,使用非常方便.Qt中使用Http协议与服务端通信的请求主要分为GET和POST,GET是从指定的资源请求数据,而POST是向指定的资源提交要被处理的数据。
从Qt4.4开始,引入了QNetworkRequest、QNetworkReply 和 QNetworkAccessManager等类来进行HTTP、FTP的操作,替代之前的QFtp和QHttp。要使用这些类,先在pro文件中引入network模块:
QT += network
网络访问API围绕一个QNetworkAccessManager对象构建。由于QNetworkAccessManager基于QObject,因此只能从它所属的线程中使用它。
创建QNetworkAccessManager对象后,应用程序就可以使用它通过网络发送请求。 该类提供了一组标准函数,它们接收请求和可选数据,每个函数都返回一个QNetworkReply对象。返回的对象用于获取响应相应请求而返回的任何数据。
QNetworkAccessManager具有异步API,当http请求完成后,会通过finished信号进行通知.
常用的函数、信号槽
QStringList supportedSchemes() const; 查看支持的协议
QNetworkReply *get(const QNetworkRequest &request); //请求获取,具有异步,当http请求完成后,会通过finished信号进行通知
信号 void finished(QNetworkReply *reply);
QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data);
//构建一个manager对象
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//manager具有异步API,当http请求完成后,会通过finished信号进行通知
connect(manager,&QNetworkAccessManager::finished,this,&MyClass::replyFinished);
//发送异步get请求
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
也可以把get设置成同步
//这里也可以用一个QEventLoop来等待请求完成,但是我更爱用槽函数
QNetworkReply *reply=manager->get(request);
QEventLoop eventLoop;
connect(reply, &QNetworkReply ::finished, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
QByteArray reply_data=reply->readAll();
要发起一个get/post请求,首先要构建一个QNetworkRequest对象作为参数,它包含一个URL和一些可用于修改请求的辅助信息
常用函数
void setUrl(const QUrl &url);
//构建请求对象
QNetworkRequest request;
request.setUrl(QUrl("http://httpbin.org/get"));
request.setRawHeader("Content-Type","application/json");
有时需要在url中携带参数,如果手动进行字符串拼接不是很方便。Qt5.0提供了 QUrlQuery类,可以很方便的拼接和解析url中的参数。参考:https://blog.csdn.net/baidu_16370559/article/details/129595560?spm=1001.2014.3001.5501
调用manager的get、post等接口后会返回一个reply对象,在manager的finished信号种也会传递该reply对象。如果要同步处理就在get、post后用事件循环等finished信号,如果是异步处理直接关联finished信号到槽即可。
常用函数:
NetworkError error() const; //获取出错信息
QString errorString() const;
QVariant attribute(QNetworkRequest::Attribute code) const; code为HttpStatusCodeAttribute,获取http的状态码
QUrl url() const; 获取url
QByteArray readAll(); //获取返回来的数据
//connect(manager,&QNetworkAccessManager::finished,this,&MyClass::replyFinished);
//槽函数
void MyClass::replyFinished(QNetworkReply *reply)
{if(reply->error()!=QNetworkReply::NoError){//处理中的错误信息qDebug()<<"reply error:"<errorString();}else{//请求方式qDebug()<<"operation:"<operation();//状态码qDebug()<<"status code:"<attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug()<<"url:"<url();//qDebug()<<"raw header:"<rawHeaderList();//获取响应信息const QByteArray reply_data=reply->readAll();qDebug()<<"read all:"<deleteLater();
}