QT QHTTP操作入门

 


 
 
最近由于要做一些关于QT方面的东西,需要访问网络,利用HTTP协议。刚刚好QT里实现了HTTP协议,即QHttp类,学习一下应该可以排上用场。
 但是QT Assistant上说:The class works asynchronously, so there are no blocking functions.也就是说这个类里面的所有的函数都是异步的,不会阻塞。当你向服务器发送了一个request后,函数立即返回,不等服务器返回response,也不管结果是成功还是失败。在发送请求后,会触发一系列事件:
                 requestStarted(2)
                        stateChanged(Connecting)
                        stateChanged(Sending)
                        dataSendProgress(77, 77)
                        stateChanged(Reading)
                        responseHeaderReceived(responseheader)
                        dataReadProgress(5388, 0)
                        readyRead(responseheader)
                        dataReadProgress(18300, 0)
                        readyRead(responseheader)
                        stateChanged(Connected)
                        requestFinished(2, false)
                        done(false)
所有的结果的处理就是通过对触发的各种事件的响应来处理的。说到QT的事件响应机制,就不能不说connect方法,还有SIGNAL和SLOT机制。connect的原型如下:
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoCompatConnection )
原理就是sender出发一个signal,然后receiver就会收到这个信号,然后调用slot指定的函数来处理这个事件。

说完了qt的现状,继续说我的需求:我想实现的系统需要的是一个同步的会阻塞的Http协议的实现,这跟QT的实现相悖。从网上搜索解决方案,找了好久,功夫不负有心人,终于找到了一些方法,但是这距离自己的实现还有一定的距离,毕竟没有亲自试验过,未必能用。网上给的思路很清楚,就是发起请求以后,让程序通过调用QEventLoop的exec方法,进入一个循环状态,等待事件相应,然后在需要的事件响应里,调用QEventLoop的exit方法强制退出循环,从而达到阻塞的目的。
有了这样一个方案,就开始朝着这个方向努力。阻塞调用http的类很快写好了,这个不太费力,
类有两个字段如下:
private:
    QHttp *http;
    QEventLoop *loop;
简单起见,直接把http请求写到构造函数了,如下所示:
MyHttp::MyHttp(char* host, char* url)
{
    loop = new QEventLoop(this);                                           // 创建QEventLoop对象
    http = new QHttp(this);                                                       // 创建QHttp对象
    connect(http, SIGNAL(done(bool)),                                    // 绑定http的done事件和httpDone处理函数
            this, SLOT(httpDone(bool)));
    http->setHost(host);                                                           // 设置要请求的服务器
    http->get(url);                                                                     // 调用get方法获取需要的网页的url
    cout<<"call get"<<endl;
    loop->exec();                                                                     // 进入循环等待
    cout<<http->readAll().constData()<<endl;                         // 循环结束,打印输出结果
}
事件响应如下:
void MyHttp::httpDone(bool res)
{
    loop->exit();                                                                       // 处理done事件,强制退出循环等待
    cout<<"the request is done: ";
    if (res)                                                                                // 根据执行情况,打印执行结果
    {  
        cout<<"failed!"<<endl;
    }  
    else
    {  
        cout<<"successful!"<<endl;
    }  
}
调用这个类的main函数实现如下:
int main(int argc, char** argv)
{
    if (argc < 3)
    {  
        cout<<"http <host> <page>"<<endl;
        return 0;
    }  
    MyHttp *mh = new MyHttp(argv[1], argv[2]);                          // 创建MyHttp对象
    return 0;
}
这个是最开始的程序,编译通过,但是执行的时候却报错了:QEventLoop: Cannot be used without QApplication。错误说的很明白,没有QApplication不能使用QEventLoop,然后就想要加一个QApplication,然后,就把调用的main函数改成下面的样子:
int main(int argc, char** argv)
{
    if (argc < 3)
    {
        cout<<"http <host> <page>"<<endl;
        return 0;
    }
    QCoreApplication app(argc, argv);                                                // 创建QCoreApplication对象
    MyHttp *mh = new MyHttp(argv[1], argv[2]);
    return app.exec();                                                                          // 进入程序循环
}
然后,再编译运行,就搞定了。现在还有个问题就是程序运行完不会自动退出,但是这个已经不影响使用了,因为这个程序的目的是实现http的同步请求。
运行结果如下:
[jason@localhost http]$ ./http www.baidu.com /index.htm
call get
the request is done: successful!
<此处略去无数字:网页的源码实在太多了,省去了……>

这个过程其实并不是特别复杂,但是遇到了各种各样的问题,中间还是学到了一些东西,所以记下了这篇笔记,供以后参考用。

写于北航,2011年5月16日

by Jason

 

转载于:https://www.cnblogs.com/MingZznet/articles/3210964.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值