您的位置:首页 > 理论基础 > 计算机网络

程序员一枚】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();  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: