Qt HTTP内部构架
QUrl url("http://qt.gitorious.org");
QNetworkRequest request(url);
QNetworkAccessManager manager;
QNetworkReply *reply = manager.get(request);
QObject::connect(reply, SIGNAL(finished()), myClass, SLOT(replyFinished()));
1. 公开接口:
以上的例子展示了主要的接口:
1.使用 QUrl 来创建被用来表示一个HTTP请求的 QNetworkRequest 。
2.该请求被传递给 QNetworkAccessManager ,该类负责在网络上发送请求,并返回一个表示HTTP响应的 QNetworkReply 。
3.根据URL所采用协议的不同, QNetworkAccessManager 会创建 QNetworkReply 的不同内部子类;如果URL采用了“http://”或者“https://”协议,则会创建一个 QNetworkReplyHttpImpl 实例。
4.该类是用来设置请求,并在发送请求前向其添加例如缓冲或者cookie等信息。
5.如果该请求被用作上传数据(例如使用HTTP POST或者PUT),该实现类会用到QNonContiguousByteDevice 。这个非连续字节类能够用来在不执行memcpy操作的环境中读取文件、字节等。
这些接口可用如下的UML图表示:
2. 工作线程:
QNetworkReplyHttpImpl 会创建一个名为 QHttpThreadDelegate 的类,并将其放置在这个新的线程中(被称为HTTP线程)。
这个 QHttpThreadDelegate 是一个 Facade 类,为所有在HTTP线程中的操作提供了一个接口。
所有在 QNetworkReplyHttpImpl 和 QHttpThreadDelegate 之间的跨线程通信和数据传递都是通过信号和槽完成的。
这意味着Delegate提供了一些槽,由HttpImpl发出的信号所触发,反之亦然。
每当 QNetworkReplyHttpImpl 被创建时,它都会创建一个相应的 QHttpThreadDelegate ,链接相应的信号和槽,并将该Delegate移动到HTTP线程中去。
该Delegate提供了用来组建HTTP请求和响应的类,名为 QHttpNetworkRequest 和QHttpNetworkReply 。
这个名字会让人困惑,因为我们已经拥有了公开接口 QNetworkRequest 和 QNetworkReply ;这两个公开接口提供了大量HTTP特有属性的访问接口,例如设置HTTP流水线、状态码和其他HTTP头。
而这两个内部类 QHttpNetworkRequest 和 QHttpNetworkRply 则用以解析从socket数据流中接受到的HTTP消息,以填充HTTP头和实体。
下图展示了将这几个类添加到类图后的结构:
3. 更底层:
HTTP请求和相应是在所谓的“频道”上进行收发的;简单的说,每个“频道”就是一个socket,并附加了一些用于维护HTTP状态和特性的逻辑。
对于普通的HTTP请求,通常采用 QTcpSocket 作为该频道上的socket,而对于“https://”则采用 QSslSocket 。
一系列连接到同一服务器的频道组成一个连接。
对于和同一个服务器的通信,这里总是只有一个连接,以及最多同时有六个频道。
此外,当HTTP流水线被启用的时候,还可以同时发出更多的请求。
当通过socket接收到一个相应时,该socket并不会被自动关闭,而是默认被用作后续请求,从而节省socket的初始化时间并重用一个已经具有更大TCP窗口值的socket。
现在,HTTP内部结构的UML图已经基本完整了:
4. 其他:
到目前还有两个重要的类未被提及:
QNetworkSession :该类主要用于移动设备之中,特别是在缺少互联网的持续连接的环境中。当缺乏对互联网的连接时, QNetworkSession 及其相关类会尝试创建一个连接(例如,程序可以连接 QNetworkSession 的信号,让用户在3G和Wifi连接之间进行选择)。该类被 QNetworkAccessManager 初始化。
QNetworkAccessAuthenticationManager :该全局类被用于存储能够被重用的认证信息。当服务器要求认证时, QNetworkAccessManager 会发出一个信号(QNetworkAccessManager::authenticationRequired()),要求用户输入用户名和密码。而这个认证管理器类则会缓存此信息,并在后续的请求中自动将其发送给服务器。有趣的是,这个认证管理器也使用了 QNetworkAccessCache ,和 QHttpNetworkConnection 用来缓存连接一样。
因此,(本文中提及的)Qt HTTP内部构架的完整类图如下所示:
还有哪些未被提及:
尽管上面这个类图已经显得够复杂了,但还有一些类和领域被省略了:
Bearer类 :用于更加细粒度的调节连接设置等,除了前面提到的 QNetworkSession 外还有几个类被用到。
Cookies :显然,Qt HTTP默认支持cookie的解析和发送,请参见 QNetworkCookie 和 QNetworkCookieJar 。
HTTP缓存 :尽管Qt也支持HTTP缓存,但未被默认启用。
代理服务器 :Qt支持在HTTP和SOCKS5代理服务器上进行网络传输。
上传数据 :一些关于上传数据,以及处理HTTP multipart消息的类被省略了。
转载自:http://www.tuicool.com/articles/U7BBrm
Qt HTTP内部构架的更多相关文章
- Qt 的内部进程通信机制
Qt 的内部进程通信机制 续欣 (xxin76@hotmail.com), 博士.大学讲师 2004 年 4 月 01 日 Qt 作为一种跨平台的基于 C++ 的 GUI 系统,能够提供给用户构造图形 ...
- QT 信号槽 异步事件驱动 单线程 多并发
利用好Qt 模块的异步信号槽,单线程同样可是实现很强悍的的并发能力.应付正常的功能是足够的. 需要注意的是:该模式本质上为 单线程 事件驱动异步模式,所以需要做的事优化你的业务代码构架以应付性能与并发 ...
- Web系统开发构架再思考-前后端的完全分离
前言 前后端完全分离其实一直是Web开发人员的梦想,也一直是我的梦想,遥想当年,无论是直接在代码里面输出HTML,还是在HTML里面嵌入各种代码,都不能让人感到满意.期间的痛苦和纠结,我想所有Web开 ...
- linux下QT Creator常见错误及解决办法
最近因为在做一个关于linux下计算机取证的小项目,需要写一个图形界面,所以想到了用QT来写,选用了linux下的集成开发环境QT Creator5.5.1,但刚刚安装好,竟然连一个"hel ...
- 关于Qt
什么是Qt Qt是一个针对桌面.嵌入式.移动设备的一个跨平台的应用程序开发框架,支持的平台包括Linux.OS X.Windows.VxWorks.QNX.Android.iOS.BlackBerry ...
- 【Qt】关于Qt【转】
什么是Qt Qt是一个针对桌面.嵌入式.移动设备的一个跨平台的应用程序开发框架,支持的平台包括Linux.OS X.Windows.VxWorks.QNX.Android.iOS.BlackBerry ...
- Qt 内存管理机制(转)
许转载http://devbean.blog.51cto.com/448512/526734 强类型语言在创建对象时总会显式或隐式地包含对象的类型信息.也就是说,强类型语言在分配对象内存空间时,总 ...
- Qt的版本历史
发展史 Qt的第一个商业版本于1995年推出,随后Qt的发展就很快了,下面是Qt发展史上的一 些里程碑,从之前的Qt1.x开始到现在的Qt5.x. Qt1-3 版本 发布日期 1.40 10 July ...
- 对QT的产品,以及QT的一些综合评论 good
QT你不能说他不流行吧, WPS, Wirshark, KDE, dropbox, skype, virtualbox都和qt有关吧, 你想写个跨平台的C++程序, QT是个不错的选择, 普通PC应用 ...
随机推荐
- MVC - HtmlHelper类
传统的Html元素不能和服务端数据进行绑定 HtmlHelper类提供了一系列的方法来生成Html元素 并可以实现与数据绑定在一起 然后生成Html Html.BeginForm(actionName ...
- Linux基础(二)
二.Linux 常用命令 一.命令行操作的流程 录入命令(可以使用各种途径来发送命令) 命令被解释器解释并执行 将结果以产品需要的方式显示出来 二.命令提示符 sq@sq-VirtualBox:~$ ...
- Windows Thrift安装及HelloWorld
Thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.org 跨 ...
- sea.js 学习
开篇:终于学习了sea.js的使用了,因为它是一个模块加载工具,所以首先要了解javascript的模块编程,然后对sea.js的了解和使用 javascript 模块编程 为什么要模块化编程,为了让 ...
- Unity3D用vistual studio打卡C#脚本卡死解决
小黑已经跟我3年了,不仅很喜欢他方正酷黑的外表,而且稳定性绝对没的说.我已经3年没有重装过系统了,而且现在装了3个系统!虽然小黑很适合程序员,但是他最大的缺点就是做设计比较吃力,显卡512M.像uni ...
- SQL Server自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- ACTIVEX 重新安装与卸载
1.卸载工具 SREngLdr.EXE,打开后执行 系统修复->浏览器加载项,找到对应的ACTIVEX,点击删除.OK 2.开发人员如遇到ACTIVEX版本更新.可在OBJECT 里加入更高版本 ...
- OC - 4.OC核心语法
一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...
- css滚动条样式
1.横向滚动条:(abeamScroll) <div style="width:400px;height:200px;overflow-x:auto;overflow-y:hidden ...
- 记一次ftp服务器错误 centOS 6.4 vsftpd 500 illegal port command
这个错误是因为是主动模式的,应该改为被动模式 以下是操作过程: iptables中加 -A INPUT -p tcp -m state --state NEW -m tcp --dport 10221 ...