博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QT QHTTP操作入门
阅读量:5015 次
发布时间:2019-06-12

本文共 2750 字,大约阅读时间需要 9 分钟。

 

 
 
最近由于要做一些关于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

你可能感兴趣的文章
第二章 Vue快速入门--20 品牌案例-完成品牌列表的添加功能+ 21 品牌案例-根据Id完成品牌的删除...
查看>>
Java单例模式
查看>>
重温WCF之消息契约(MessageContract)(六)
查看>>
Excel2007制作直方图和正态分布曲线图
查看>>
android adb常用指令
查看>>
Android框架之路——GreenDao3.2.2的使用
查看>>
类方法WCF学习笔记-KnowTypeAttribute用法
查看>>
平台程序微信平台开发应用的签名
查看>>
程序卡OK6410裸板更新程序_update
查看>>
MYSQL用户名:root
查看>>
JavaScript 开发规范要求
查看>>
Devstack 安装OpenStack Pike版本(单机环境)
查看>>
Javascript 函数初探
查看>>
类的定义、声明使用
查看>>
转载,gini系数代码对应的公式
查看>>
编译安装mysql-5.6.40
查看>>
年终总结
查看>>
初创互联网公司技术架构变迁之路
查看>>
【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)
查看>>
【网络流24题】No. 13 星际转移问题 (网络判定 最大流)
查看>>