Qt网络编程散记-01

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>
在看了foruok的 Qt Quick 之 QML 与 C++ 混合编程详解后,我决定在qt 4.8.1环境下试一试
然后就遇到了一些问题
 自己写了个HttpManager类,在将其注册到qml中,调用的时候如下

NetworkManager {
        id:net
        url:"http://www.baidu.com"
        method:NetworkManager.GET
}

上述的networkManager元素的方法为net.start()

使用start()方法后,就会向" http://www.baidu.com"请求GET
在将返回的数据写到一个文件里

在qml中第一次触发start(),往文件里写的是一个html内容
再一次在qml中触发start(),往文件里写的才是" http://www.baidu.com"的html文件的gzip

前后两次调用start()方法,GET到的内容是不一样的

第一次GET到的内容如下

<html>
<head>
<script language="javascript">setTimeout("location.replace(location.href.split(\"#\")[0])",2000);</script>
<script type="text/javascript" src="http://61.142.67.130:89/cookie/flash.js"></script>
<script language="javascript">setURL("61.142.67.130");supFlash();</script>
</head>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="0" height="0" id="m" align="center"><param name="allowScriptAccess" value="always" />
<param name="movie" value="http://61.142.67.130:89/cookie/flashcookie.swf" />
<param name="quality" value="high" />
<param name="FlashVars" value="fc=2308725444419&f=1346948874" />
<embed src="http://61.142.67.130:89/cookie/flashcookie.swf"FlashVars="fc=2308725444419&f=1346948874" quality="high" width="0" height="0"  name="m" align="center" allowScriptAccess="always" type="application/x-shockwave-flash"pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</body>
</html>

 在C++代码中,测试的时候,出现的是间隔问题,
若第一次启动程序(随便启动 HttpManager::start()方法),成功获取正确的网页,那么在下一次启动程序时,便会获取上述的html代码。
在第三次启动程序的时候,又能重新获取正确的网页,诸如...

遇到的问题,不知是我的HttpManager类写的有问题(我对网络编程还不是很熟,可能是我的C++代码中的HttpManager类没写好吧)
贴一下我写的Qt 的HttpManager类的头文件(已经设置可以注册到qml,也可以在c++代码中使用)

#ifndef HTTPMANAGER_H
#define HTTPMANAGER_H

#include <QString>
#include <QUrl>
#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>

class HttpManager : public QObject
{
    Q_OBJECT
    Q_ENUMS(HTTPMETHOND)
    Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
    Q_PROPERTY(HTTPMETHOND methond READ methond WRITE setMethond NOTIFY methondChanged)

public:
    enum HTTPMETHOND {
        NONE = 0,
        GET = 1,
        POST = 2,
        HEAD = 3,
        PUT = 4,
        DELETE = 5
    };

    /*标记构造次数*/
    static int index;

    explicit HttpManager(QObject *parent = 0);
    ~HttpManager();


    /*property url*/
    QUrl url() const;
    void setUrl(const QUrl &_url);

    /*property methond*/
    HTTPMETHOND methond() const;
    void setMethond(HTTPMETHOND _Methond);

    Q_INVOKABLE void postData(QString _postData);

signals:
    void urlChanged(const QUrl &_url);
    void methondChanged(HTTPMETHOND _Methond);
    void finished();

public slots:
    void start();

private:
    void HTTPGet();
    void HTTPPost();

protected:
    void setRequsetRawHeaders(const QString &_headerName,const QString &_headerValue);

private slots:
    void replyFinished(QNetworkReply* _reply);

private:
    QNetworkAccessManager *mManager;
    QString *mPostData;
    QUrl *mUrl;
    HTTPMETHOND mMethond;

    QNetworkReply *mReply;
    QNetworkRequest *mRequest;
    QList<QNetworkCookie>  mCookies;

};

#endif // HTTPMANAGER_H

Networkmanager类的实现
#include <QDebug>
#include <QByteArray>
#include <QSslConfiguration>
#include <QFile>
#include <QDir>

#include "httpmanager.h"

/*标记构造次数*/
int HttpManager::index = 0;

HttpManager::HttpManager(QObject *parent) :
    QObject(parent)
  ,mManager(new QNetworkAccessManager)
  ,mPostData(new QString)
  ,mUrl(new QUrl)
  ,mMethond(NONE)
  ,mRequest(new QNetworkRequest)
{
    /*标记构造次数*/
    index++;

    qDebug() << "index:" << index <<"here is the http manager!";
    mManager->setCookieJar(new QNetworkCookieJar(this));
    connect(mManager, SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*)));
}

HttpManager::~HttpManager()
{
    delete mUrl;
    delete mPostData;
    delete mRequest;
    mReply->deleteLater();
    mManager->deleteLater();
}

void HttpManager::start()
{

    this->setRequsetRawHeaders("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0");
    this->setRequsetRawHeaders("Accept","*/*");
    this->setRequsetRawHeaders("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
    this->setRequsetRawHeaders("Accept-Encoding","gzip, deflate");
    this->setRequsetRawHeaders("DNT","1");
//    this->setRequsetRawHeaders("Referer","https://ui.ptlogin2.qq.com/cgi-bin/logindaid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20140612002");

    mRequest->setUrl(*mUrl);

    switch(mMethond)
    {
    case NONE:
        qDebug() << "error!";
        break;

    case GET:
        qDebug() << "get methond";
        this->HTTPGet();
        break;

    case POST:
        qDebug() << "post methond";
        break;

    case HEAD:
        qDebug() << "head methond";
        break;

    case PUT:
        qDebug() << "put methond";
        break;

    case DELETE:
        qDebug() << "delete methond";
        break;

    default:
        break;
    }
}

void HttpManager::HTTPGet()
{
    mReply = mManager->get(*mRequest);
}

void HttpManager::HTTPPost()
{
    mReply = mManager->post(*mRequest,mPostData->toAscii());
}

QUrl HttpManager::url() const
{
    return *mUrl;
}

void HttpManager::setUrl(const QUrl &_url)
{
    *mUrl = _url;
    mRequest->setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");

    if (mUrl->scheme() == "https")
    {
        QSslConfiguration config;
        config.setPeerVerifyMode(QSslSocket::VerifyNone);
        config.setProtocol(QSsl::TlsV1);
        mRequest->setSslConfiguration(config);
    }

    emit urlChanged(*mUrl);
}

HttpManager::HTTPMETHOND HttpManager::methond() const
{
    return mMethond;
}

void HttpManager::setMethond(HTTPMETHOND _Methond)
{
    mMethond = _Methond;
    emit methondChanged(mMethond);
}

void HttpManager::postData(QString _postData)
{
    *mPostData = _postData;
    qDebug() << "mPostData:" << *mPostData;
}

void HttpManager::replyFinished(QNetworkReply *reply)
{
    QFile *_tempFile = new QFile;

    QString _file = "D://html.gz";

    _tempFile->setFileName(_file);

    if (mReply->error() != QNetworkReply::NoError)
    {
        qWarning() << "ERROR:" << mReply->errorString();
        return;
    }
    else
    {
        if(!_tempFile->open(QFile::WriteOnly))
        {
            qDebug() << "can't open file for write";
            return;
        }

        _tempFile->write(reply->readAll());
        _tempFile->close();
    }

}

void HttpManager::setRequsetRawHeaders(const QString &_headerName,const QString &_headerValue)
{
    QByteArray _tempHeaderName = _headerName.toAscii();
    QByteArray _tempHeaderValue = _headerValue.toAscii();
    mRequest->setRawHeader(_tempHeaderName,_tempHeaderValue);
}

在qml中调用NetworkManager类
import QtQuick 1.1
import com.qyvlik.NetworkManager 1.0

Rectangle {
    width: 400
    height: 400

    NetworkManager {
        id:net
        url:"http://www.baidu.com"
        methond:NetworkManager.GET
    }

    Text {
        width: parent.width-10
        wrapMode: Text.WrapAnywhere
        anchors.centerIn:parent
        id: text
        text: net.url;
        font.family: "华文细黑"
        font.pointSize: 11
        horizontalAlignment: Text.AlignHCenter
    }

    Rectangle {
        id:button
        width:100
        height: 60
        color:"#7f92b3"
        radius: 10
        border.width: 2
        border.color: "black"

        Text {
            id: buttonText
            text: qsTr("start!")
            anchors.centerIn:parent
        }

        anchors.right: parent.right
        anchors.rightMargin: 10
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 10

        MouseArea {
            id:buttonArea
            anchors.fill: button
            onClicked: {
                net.start();
            }
        }
    }
}

在贴一下在么把c++代码注册到qml 中去吧
qmlRegisterType<HttpManager>("com.qyvlik.NetworkManager", 1, 0, "NetworkManager");
将HttpManager注册到qml中去,模块名为com.qyvlik.NetworkManager,主版本号为1,副本为0,element名为NetworkManager






你可能感兴趣的:(网络编程,qt,qml,QtQuick)