目录
将 TCP 与 QTcpSocket 和 QTcpServer 一起使用
使用 Qt 进行网络编程
Qt Network 模块提供了允许您编写 TCP/IP 客户端和服务器的类。 的低级类,例如 QTcpSocket 、 QTcpServer 和 QUdpSocket 了代表低级网络概念 QNetworkRequest 、 QNetworkReply 和 QNetworkAccessManager 以使用通用协议执行网络操作。 它还提供了诸如 QNetworkConfiguration、QNetworkConfigurationManager 和 QNetworkSession 等实现承载管理的类。
Qt 的网络编程类
。 Qt Network C++ Classes 页面包含 Qt Network 中的 C++ 类列表
HTTP 和 FTP 的高级网络操作
网络访问 API 是用于执行常见网络操作的类的集合。 API 为所使用的特定操作和协议(例如,通过 HTTP 获取和发布数据)提供了一个抽象层,并且只公开了通用或高级概念的类、函数和信号。
网络请求由 QNetworkRequest 类表示,它还充当与请求相关的信息的通用容器,例如任何标头信息和使用的加密。 构造请求对象时指定的 URL 确定了用于请求的协议。 目前支持上传和下载 HTTP、FTP 和本地文件 URL。
网络操作的协调由 QNetworkAccessManager 类执行。 一旦创建了一个请求,这个类就被用来分派它并发出信号来报告它的进度。 管理器还协调使用 cookie 在客户端上存储数据、身份验证请求以及代理的使用。
对网络请求的回复由 QNetworkReply 类表示; 由 QNetworkAccessManager 发送请求时 提供的信号 QNetworkReply 可用于单独监控每个回复,或者开发人员可以选择为此目的使用管理器的信号并丢弃对回复的引用。 由于 QNetworkReply 是 QIODevice 因此可以同步或异步处理回复; 即,作为阻塞或非阻塞操作。
每个应用程序或库都可以创建一个或多个 QNetworkAccessManager 来处理网络通信。
将 TCP 与 QTcpSocket 和 QTcpServer 一起使用
TCP(传输控制协议)是大多数 Internet 协议(包括 HTTP 和 FTP)用于数据传输的低级网络协议。 它是一种可靠的、面向流的、面向连接的传输协议。 它特别适用于数据的连续传输。
了 QTcpSocket 一个接口。 您可以使用 QTcpSocket 来实现标准的网络协议,例如 POP3、SMTP 和 NNTP,以及自定义协议。
在开始任何数据传输之前,必须与远程主机和端口建立 TCP 连接。 一旦建立了连接,就可以通过 QTcpSocket::peerAddress () 和 QTcpSocket::peerPort () 获得对端的 IP 地址和端口。 任何时候,对端都可以关闭连接,然后数据传输将立即停止。
QTcpSocket 异步工作并发出信号以报告状态更改和错误,就像 QNetworkAccessManager 。 它依靠事件循环来检测传入数据并自动刷新传出数据。 将数据写入套接字 QTcpSocket::write () QTcpSocket::read () 读取数据。 QTcpSocket 代表两个独立的数据流:一个用于读取,一个用于写入。
由于 QTcpSocket 继承 了 QIODevice ,您可以将它与 QTextStream 和 QDataStream 。 从 QTcpSocket 确保有足够的数据可用 QTcpSocket::bytesAvailable ()
如果您需要处理传入的 TCP 连接(例如,在服务器应用程序中),请使用 QTcpServer 类。 调用 QTcpServer::listen () 设置服务器,并连接到 QTcpServer::newConnection () 信号,该信号为每个连接的客户端发出一次。 在您的插槽中,调用 QTcpServer::nextPendingConnection () 以接受连接并使用返回的 QTcpSocket 与客户端进行通信。
尽管它的大部分功能都是异步工作的,但也可以同步使用 QTcpSocket (即阻塞)。 要获得阻塞行为,请调用 QTcpSocket 的 waitFor...() 函数; 这些暂停调用线程,直到发出信号。 例如,调用非阻塞 QTcpSocket::connectToHost ()函数后,调用 QTcpSocket::waitForConnected ()阻塞线程,直到 connected() 发出
同步套接字通常会导致代码具有更简单的控制流。 waitFor...() 方法的主要缺点是在 waitFor...() 函数阻塞时不会处理事件。 如果在 GUI 线程中使用,这可能会冻结应用程序的用户界面。 因此,我们建议您仅在非 GUI 线程中使用同步套接字。 当同步使用时, QTcpSocket 不需要事件循环。
了 Fortune Client 和 Fortune Server 如何使用 QTcpSocket 和 QTcpServer 来编写 TCP 客户端-服务器应用程序。 另请参阅 Blocking Fortune Client 的示例, QTcpSocket 在单独的线程(不使用事件循环)中 Threaded Fortune Server 每个活动客户端一个线程的多线程 TCP 服务器的示例,
将 UDP 与 QUdpSocket 一起使用
UDP(用户数据报协议)是一种轻量级的、不可靠的、面向数据报的、无连接的协议。 当可靠性不重要时可以使用它。 例如,报告时间的服务器可以选择 UDP。 如果带有时间的数据报丢失,客户端可以简单地发出另一个请求。
类 QUdpSocket 允许您发送和接收 UDP 数据报。 它继承 QAbstractSocket ,因此它共享 QTcpSocket 的大部分接口。 主要区别在于 QUdpSocket 以数据报而不是连续数据流的形式传输数据。 简而言之,数据报是一个大小有限的数据包(通常小于 512 字节),除了正在传输的数据之外,还包含数据报发送方和接收方的 IP 地址和端口。
QUdpSocket 支持 IPv4 广播。 广播通常用于实现网络发现协议,例如查找网络上的哪个主机拥有最多的空闲硬盘空间。 一台主机将数据报广播到所有其他主机接收的网络。 收到请求的每台主机随后都会使用其当前的可用磁盘空间量将回复发送回发送者。 发起方等待,直到收到所有主机的回复,然后可以选择空闲空间最多的服务器来存储数据。 要广播数据报,只需将其发送到特殊地址 QHostAddress::Broadcast (255.255.255.255) 或本地网络的广播地址。
QUdpSocket::bind () 为接受传入数据报准备套接字,很像 QTcpServer::listen ()。 每当一个或多个数据报到达时, QUdpSocket 就会发出 readyRead() 信号。 调用 QUdpSocket::readDatagram () 读取数据报。
器 广播发送 和 广播接收器 示例展示了如何使用 Qt 编写 UDP 发送器和 UDP 接收器。
QUdpSocket 还支持多播。 了 Multicast Sender 和 Multicast Receiver 如何使用编写 UDP 多播客户端。
使用 QHostInfo 解析主机名
在建立网络连接之前, QTcpSocket 和 QUdpSocket 执行名称查找,将您要连接的主机名转换为 IP 地址。 此操作通常使用 DNS(域名服务)协议执行。
QHostInfo 提供了一个静态函数,可让您自己执行此类查找。 调用 QHostInfo::lookupHost 使用主机名、 QObject 指针和槽签名 QHostInfo 将执行名称查找并在结果准备好时调用给定的槽。 实际的查找是在一个单独的线程中完成的,利用操作系统自己的方法来执行名称查找。
QHostInfo 的静态函数 QHostInfo::fromName ,它将主机名作为参数并返回结果。 在这种情况下,名称查找是在与调用者相同的线程中执行的。 此重载对于非 GUI 应用程序或在单独的非 GUI 线程中进行名称查找很有用。 (在 GUI 线程中调用此函数可能会导致您的用户界面冻结,而函数在执行查找时会阻塞。)
支持网络代理
与 Qt 的网络通信可以通过代理来执行,代理可以指导或过滤本地和远程连接之间的网络流量。
各个代理由 QNetworkProxy 类表示,该类用于描述和配置与代理的连接。 支持在不同级别的网络通信上运行的代理类型,SOCKS 5 支持允许在低级别代理网络流量,HTTP 和 FTP 代理在协议级别工作。 请参阅 QNetworkProxy::ProxyType 。
代理可以基于每个套接字或应用程序中的所有网络通信启用。 新打开的套接字可以通过在连接之前调用其 QAbstractSocket::setProxy () 函数来使用代理。 ,可以为所有后续套接字连接启用应用程序范围的代理 QNetworkProxy::setApplicationProxy () 函数
代理工厂用于创建代理使用策略。 QNetworkProxyFactory 根据对特定代理类型的查询提供代理。 查询本身被编码在 QNetworkProxyQuery 对象中,这些对象可以根据关键条件选择代理,例如代理的目的(TCP、UDP、TCP 服务器、URL 请求)、本地端口、远程主机和端口以及中的协议使用(HTTP、FTP 等)。
QNetworkProxyFactory::proxyForQuery () 用于直接查询工厂。 可以通过将工厂传递给 QNetworkProxyFactory::setApplicationProxyFactory () 来实现应用程序范围的代理策略,并且可以通过继承 QNetworkProxyFactory 创建自定义代理 策略 ;