使用 Qt Network 进行网络编程
Qt Network 模块提供的类允许您编写 TCP/IP 客户端和服务器。它提供了低级类(如QTcpSocket 、QTcpServer 和QUdpSocket )和高级类(如QNetworkRequest 、QNetworkReply 和QNetworkAccessManager ),前者代表低级网络概念,后者则使用通用协议执行网络操作。
Qt 网络编程类
该 Qt Network C++ Classes页面包含Qt Network 中的 C++ 类列表。
HTTP 高级网络操作
网络访问 API(Network Access API)是执行常用网络操作的类集合。该 API 为特定的操作和协议(例如,通过 HTTP 获取和发布数据)提供了一个抽象层,仅公开了一般或高级概念的类、函数和信号。
网络请求由QNetworkRequest 类表示,该类也是与请求相关的信息(如任何头信息和使用的加密)的通用容器。构建请求对象时指定的 URL 决定了请求所使用的协议。目前,上传和下载都支持 HTTP 和本地文件 URL。
网络操作的协调由QNetworkAccessManager 类执行。请求创建后,该类将用于分派请求,并发出信号报告请求的进展情况。管理器还负责协调cookies 的使用,以便在客户端存储数据、验证请求和代理的使用。
网络请求的回复由QNetworkReply 类表示;这些回复由QNetworkAccessManager 在发送请求时创建。QNetworkReply 提供的信号可用于单独监控每个回复,开发人员也可以选择使用管理器的信号来实现这一目的,并放弃对回复的引用。由于QNetworkReply 是QIODevice 的子类,因此回复可以同步或异步处理,即阻塞或非阻塞操作。
每个应用程序或库都可以创建一个或多个QNetworkAccessManager 实例来处理网络通信。
用 QTcpSocket 和 QTcpServer 使用 TCP
TCP(传输控制协议)是大多数互联网协议(包括 HTTP 和 FTP)用于数据传输的低级网络协议。它是一种可靠、面向流、面向连接的传输协议。它特别适用于数据的连续传输。
QTcpSocket 类为 TCP 提供了一个接口。您可以使用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...() 函数阻塞时,事件将不会被处理。如果在图形用户界面线程中使用,这可能会冻结应用程序的用户界面。因此,我们建议只在非图形用户界面线程中使用同步套接字。同步使用时,QTcpSocket 不需要事件循环。
Fortune Client和Fortune Server示例展示了如何使用QTcpSocket 和QTcpServer 编写 TCP 客户端-服务器应用程序。有关如何在单独线程中使用同步QTcpSocket 的示例(无需使用事件循环),请参阅Blocking Fortune Client;有关多线程 TCP 服务器(每个活动客户端使用一个线程)的示例,请参阅Threaded Fortune Server。
用 QUdpSocket 使用 UDP
UDP(用户数据报协议)是一种轻量级、不可靠、面向数据报的无连接协议。当可靠性不重要时,可以使用它。例如,报告时间的服务器可以选择 UDP。如果丢失了包含时间的数据报,客户端只需发出另一个请求即可。
QUdpSocket 类允许发送和接收 UDP 数据报。它继承了QAbstractSocket ,因此共享了QTcpSocket 的大部分接口。主要区别在于QUdpSocket 以数据报的形式传输数据,而不是以连续数据流的形式传输数据。简而言之,数据报是一个大小有限(通常小于 512 字节)的数据包,除了传输的数据外,还包含数据报发送方和接收方的 IP 地址和端口。
QUdpSocket 支持 IPv4 广播。广播通常用于执行网络发现协议,例如查找网络上哪台主机拥有最大的可用硬盘空间。一台主机向网络广播一个数据报,所有其他主机都会收到。收到请求的每台主机都会向发送者发送一个回复,并说明其当前的可用磁盘空间量。发送者等到收到所有主机的回复后,就可以选择可用空间最大的服务器来存储数据。要广播数据报,只需将其发送到特殊地址 (255.255.255.255) 或本地网络的广播地址。QHostAddress::Broadcast
QUdpSocket::bind()会准备好接受数据报的套接字,就像QTcpServer::listen() 用于 TCP 服务器一样。每当一个或多个数据报到达时,QUdpSocket 就会发出readyRead() 信号。调用QUdpSocket::readDatagram() 读取数据报。
广播发送器和广播接收器示例展示了如何使用 Qt 编写 UDP 发送器和 UDP 接收器。
QUdpSocket 该示例还支持组播。多播发送器(Multicast Sender)和多播接收器(Multicast Receiver)示例展示了如何使用 Qt 编写 UDP 多播客户端。
使用 QHostInfo 解析主机名
在建立网络连接之前,QTcpSocket 和QUdpSocket 会执行名称查询,将要连接的主机名称转换为 IP 地址。这一操作通常使用 DNS(域名服务)协议。
QHostInfo 在此,我们提供了一个静态函数,让您可以自行执行此类查询。通过使用主机名、 指针和槽签名调用 () , 将执行名称查找,并在结果出来后调用给定的槽。实际查找是在一个单独的线程中进行的,利用操作系统自己的方法来执行名称查找。QObject QHostInfo::lookupHost QHostInfo
QHostInfo 此外,ASP.NET 还提供了一个名为 () 的静态函数,该函数以主机名为参数并返回结果。在这种情况下,名称查询是在与调用者相同的线程中进行的。该重载对于非图形用户界面应用程序或在单独的非图形用户界面线程中进行名称查询非常有用。(在 GUI 线程中调用此函数可能会导致用户界面冻结,因为函数在执行查找时会阻塞)。QHostInfo::fromName
支持网络代理
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 来创建自定义代理策略;详情请查看类文档。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.