程序员一枚】Qt网络开发之QNetworkAccessManager的使用
2013-08-03 00:31
393 查看
最近使用Qt实现一个C/S的应用,结构比较有意思,相信很多人做过C/S的应用,也已经有很多成熟的架构。但是我这个东西还是不一样的。
我们公司有成熟的服务器产品,基于B/S的,SOA结构,浏览器富客户端的应用。我想直接使用这个服务器产品,采用一个相对成熟的产品对我来说有几点好处:一是不需要考虑并发,已有的成熟的产品在并发性能上还是比较稳定的;二是不需要封转服务器端,服务器产品公司会更新和维护,节约大量的成本。
对于我目前从事的行业来说,大多数的应用是基于QT的,很少有浏览器的应用,所以需要封装一个基于Qt的客户端SDK。
所以就有了今天的应用,使用Qt封装一个基于Http协议异步的客户端SDK。
在Qt中直接使用QNetworkAccessManager可以直接进行Http的请求(QHttp已经不被推荐使用),而QNetworkAccessManager的请求和接收数据本身就是异步的。
但是基于QNetworkAccessManager的封装设计着实让我头疼了一个多月。
采用异步对我来说是一个全新的课题,所以一直在看Webkit的源码。
附上一个链接,这篇Blog详细介绍了Webkit的结构:
http://blog.csdn.net/dlmu2001/article/details/6164873
本人设计经验不足,对Qt还有点学艺不精,当时网上也没有一些很详尽的设计参考。
经过一个多月的查找和实践,把一些心得分享给大家。
要点一:对于一个应用程序,一个QNetworkAccessManager就足够了,当然使用多个QNetworkAccessManager也是没有问题的,Webkit中一个QWebpage只会使用一个QNetworkAccessManager。
要点二:每一个回复QNetworkReply都需要删除,否则会出现内存泄露,根据Qt的帮助文档,在接收完数据的槽中使用deleteLater(),防止内存泄露。
先附上设计代码(其实在Qt最新的版本中有很好的例子,大家可以参考Qt的Demo中的例子):
MyNetManager.h
[cpp] view
plaincopy
#ifndef MYNETMANAGER_H_
#define MYNETMANAGER_H_
#include <QUrl>
#include <QByteArray>
class QNetworkAccessManager;
class MyNetManager : public QObject
{
Q_OBJECT
public:
MyNetManager(QNetworkAccessManager *pManager);
~MyNetManager();
bool get(QUrl url);
bool post(QUrl url,QByteArray& bytes);
signals:
void downloadProgress( qint64 bytesSent, qint64 bytesTotal);
public slots:
void finished();
private:
QNetworkAccessManager *m_pManager;
};
#endif
MyNetManager.cpp
[cpp] view
plaincopy
#include "MyNetManager.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
MyNetManager::MyNetManager( QNetworkAccessManager *pManager )
:m_pManager(pManager)
{}
MyNetManager::~MyNetManager()
{}
bool MyNetManager::get( QUrl url )
{
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = m_pManager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(finished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(downloadProgress(qint64,qint64)));
return true;
}
bool MyNetManager::post( QUrl url,QByteArray& bytes )
{
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = m_pManager->post(request,bytes);
connect(reply, SIGNAL(finished()), this, SLOT(finished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(downloadProgress(qint64,qint64)));
return true;
}
void MyNetManager::finished()
{
QNetworkReply* reply = (QNetworkReply*)sender();
//数据处理
reply->deleteLater();
}
我们公司有成熟的服务器产品,基于B/S的,SOA结构,浏览器富客户端的应用。我想直接使用这个服务器产品,采用一个相对成熟的产品对我来说有几点好处:一是不需要考虑并发,已有的成熟的产品在并发性能上还是比较稳定的;二是不需要封转服务器端,服务器产品公司会更新和维护,节约大量的成本。
对于我目前从事的行业来说,大多数的应用是基于QT的,很少有浏览器的应用,所以需要封装一个基于Qt的客户端SDK。
所以就有了今天的应用,使用Qt封装一个基于Http协议异步的客户端SDK。
在Qt中直接使用QNetworkAccessManager可以直接进行Http的请求(QHttp已经不被推荐使用),而QNetworkAccessManager的请求和接收数据本身就是异步的。
但是基于QNetworkAccessManager的封装设计着实让我头疼了一个多月。
采用异步对我来说是一个全新的课题,所以一直在看Webkit的源码。
附上一个链接,这篇Blog详细介绍了Webkit的结构:
http://blog.csdn.net/dlmu2001/article/details/6164873
本人设计经验不足,对Qt还有点学艺不精,当时网上也没有一些很详尽的设计参考。
经过一个多月的查找和实践,把一些心得分享给大家。
要点一:对于一个应用程序,一个QNetworkAccessManager就足够了,当然使用多个QNetworkAccessManager也是没有问题的,Webkit中一个QWebpage只会使用一个QNetworkAccessManager。
要点二:每一个回复QNetworkReply都需要删除,否则会出现内存泄露,根据Qt的帮助文档,在接收完数据的槽中使用deleteLater(),防止内存泄露。
先附上设计代码(其实在Qt最新的版本中有很好的例子,大家可以参考Qt的Demo中的例子):
MyNetManager.h
[cpp] view
plaincopy
#ifndef MYNETMANAGER_H_
#define MYNETMANAGER_H_
#include <QUrl>
#include <QByteArray>
class QNetworkAccessManager;
class MyNetManager : public QObject
{
Q_OBJECT
public:
MyNetManager(QNetworkAccessManager *pManager);
~MyNetManager();
bool get(QUrl url);
bool post(QUrl url,QByteArray& bytes);
signals:
void downloadProgress( qint64 bytesSent, qint64 bytesTotal);
public slots:
void finished();
private:
QNetworkAccessManager *m_pManager;
};
#endif
MyNetManager.cpp
[cpp] view
plaincopy
#include "MyNetManager.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
MyNetManager::MyNetManager( QNetworkAccessManager *pManager )
:m_pManager(pManager)
{}
MyNetManager::~MyNetManager()
{}
bool MyNetManager::get( QUrl url )
{
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = m_pManager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(finished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(downloadProgress(qint64,qint64)));
return true;
}
bool MyNetManager::post( QUrl url,QByteArray& bytes )
{
QNetworkRequest request;
request.setUrl(url);
QNetworkReply *reply = m_pManager->post(request,bytes);
connect(reply, SIGNAL(finished()), this, SLOT(finished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),this,SIGNAL(downloadProgress(qint64,qint64)));
return true;
}
void MyNetManager::finished()
{
QNetworkReply* reply = (QNetworkReply*)sender();
//数据处理
reply->deleteLater();
}
相关文章推荐
- Qt网络开发之QNetworkAccessManager使用要点
- Qt网络编程之QNetworkAccessManager
- Qt通过QNetworkAccessManager实现Http网络通信
- Qt 访问网络的 HttpClient(封装QNetworkAccessManager,且有服务端)
- Qt网络编程之QNetworkAccessManager
- Qt网络编程之QNetworkAccessManager
- qt 的QNetworkAccessManager的使用和防止内存泄漏
- QNetworkAccessManager(网络访问管理器)
- 关于qt QSqlDatabase::database(connectionName) 和QNetworkAccessManager::post()导致卡死的情况
- QT QNetworkAccessManager跳转URL处理
- <h3>QT中使用QNetworkAccessManager类进行POST数据
- Qt---QNetworkAccessManager
- Qt之QNetworkAccessManager
- QNetworkAccessManager(网络访问管理器)
- 【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程<二>
- QT QNetworkAccessManager demo
- QNetworkAccessManager 的使用
- 【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程
- QT QNetworkAccessManager 如何支持RESTFul的HTTP Patch方法
- 通过QEventLoop实现网络请求QNetworkAccesssManager阻塞