八年了Qt6终于来啦!Qt Network模块发生重大更改

在本文中 , 我们想告诉您Qt Network模块在Qt 6中的一些最新更新和更改 。 以及一些潜在的发展
QNetworkAccessBackend
QNetworkAccessBackend是一个抽象基类 , 用于与我们的缓存 , 文件和ftp后端接口 。 我们已经在Qt中使用QNetworkAccessBackend已有一段时间了 , 但是不可能以任何合理的方式在Qt网络外部使用 。 对于Qt 6 , 我们计划将ftp后端移出Qt Network , 并作为插件单独分发 。 为此 , 我们使QNetworkAccessBackend在外部使用起来更加友好 , 并使QNetworkAccessManager能够在运行时加载这些插件 。 与我们的某些其他插件接口一样 , 它没有Qt本身具有的严格的向后兼容性保证 , 并且需要链接到QtNetworkPrivate才能使用它 。
我们希望能够专门化各种后端的行为 。 例如 , 非网络后端不需要我们为目标URL准备代理列表 。 为此 , 我们添加了三个不同的枚举 , 每个枚举中都有一些值:

  • TargetType
  • 安全功能
  • IO功能
其中 , 仅需要“ TargetType”指定后端支持的目标是联网的还是本地的 。
如果某些功能无法使用 , 则某些功能可能无法启用 。 一个这样的例子是IO功能“ZeroCopy” , 它启用函数readPointer()和advanceReadPointer() 。 如果未启用 , 则不会调用这两个函数 。 拥有这个特性系统的主要思想是我们可以在不破坏任何现有代码的情况下进行这些改进 。 新代码必须选择使用新功能 。 不过 , 重申一下:我们不能保证网络访问后端插件与使用Qt的应用程序具有相同的向后兼容性 。
要实现网络访问后端插件 , 您需要实现一个从QNetworkAccessBackendFactory继承的类 。 如果支持所请求的方案 , 则此类将完成创建后端的工作 。 您还需要创建一个从QNetworkAccessBackend继承的类 , 并覆盖所有纯虚函数以及'read()'或'readPointer()'和'advanceReadPointer()'(如果您的类支持'ZeroCopy'功能)。 对于现有用途 , QNetworkAccessCacheBackend和QNetworkAccessFileBackend均已更新为使用新接口 , 尽管它们直接编译为Qt而不是作为插件分发 。
通讯协定
在Qt 6中 , 我们放弃了SPDY支持 。 SPDY是具有开放规范的实验性协议 , 主要由Google开发 。 SPDY成为HTTP / 2协议的前身和原型 。
在维持与HTTP / 1.1的兼容性(例如与方法 , 状态代码 , URI和大多数标头字段)的兼容性的同时 , HTTP / 2还添加了:
  • HTTP标头的数据压缩
  • 通过单个TCP连接多路复用多个请求
  • HTTP / 2服务器推送
  • 允许客户端和服务器选择HTTP / 2或HTTP / 1.1的协商机制
在Qt 6之前 , 必须通过设置以下属性之一来手动启用HTTP / 2协议:
  • QNetworkRequest :: Http2AllowedAttribute
  • QNetworkRequest :: Http2DirectAttribute ,
例如:
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);对于“ Http2AllowedAttribute” , QNetworkAccessManager对“ https”方案使用应用程序层协议协商 , 对“ http”方案使用协议升级头“ h2c” 。 如果您事先知道服务器以所谓的“直接”模式支持HTTP / 2 , 而无需协议协商 , 则第二个属性很有用 。
在Qt 6中 , 默认情况下启用HTTP / 2支持:这意味着属性'Http2AllowedAttribute'设置为'true' 。 如果无法协商HTTP / 2 , 则QNetworkAccessManager将回退到HTTP / 1.1 。 如果您的应用程序只能使用HTTP / 1.1 , 则可以为新的网络请求将属性'Http2AllowedAttribute'设置为'false':
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);此“默认启用”规则有一个例外:
QNetworkAccessManager::connectToHostEncrypted(host, port, configuration);