文章目录
- QAbstractSocket 介绍
- 公共类型
- 公共函数
- void abort()
- bool bind(const QHostAddress &address, quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
- bool bind(quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
- virtual void connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocol protocol = AnyIPProtocol)
- void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite)
- [virtual] void QAbstractSocket::disconnectFromHost()
- QAbstractSocket::SocketError QAbstractSocket::error() const
- bool QAbstractSocket::flush()
- [override virtual] bool QAbstractSocket::isSequential() const
- bool QAbstractSocket::isValid() const
- QHostAddress QAbstractSocket::localAddress() const
- quint16 QAbstractSocket::localPort() const
- QHostAddress QAbstractSocket::peerAddress() const
- QString QAbstractSocket::peerName() const
- quint16 QAbstractSocket::peerPort() const
- QString QAbstractSocket::protocolTag() const
- QNetworkProxy QAbstractSocket::proxy() const
- qint64 QAbstractSocket::readBufferSize() const
- [override virtual protected] qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
- [override virtual protected] qint64 QAbstractSocket::readLineData(char *data, qint64 maxlen)
- [virtual] void QAbstractSocket::resume()
- [virtual] bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = ConnectedState, QIODevice::OpenMode openMode = ReadWrite)
- [protected] void QAbstractSocket::setSocketError(QAbstractSocket::SocketError socketError)
- [virtual] bool QAbstractSocket::waitForConnected(int msecs = 30000)
- [virtual] bool QAbstractSocket::waitForDisconnected(int msecs = 30000)
- bool QAbstractSocket::waitForReadyRead(int msecs = 30000)
- [override virtual protected] qint64 QAbstractSocket::writeData(const char *data, qint64 size)
QAbstractSocket 介绍
QAbstractSocket是QTcpSocket和QUdpSocket的基类,包含这两个类的所有常见功能。
如果你需要一个套接字,你有两个选择:
-
实例化QTcpSocket或QUdpSocket。
-
创建一个本机套接字描述符,实例化QAbstractSocket,并调用setSocketDescriptor()来包装本机套接字。
引入 Header:
#include
引入 qmake:
QT += network
继承自 Inherits:
QIODevice
被继承 Inherited By:
QTcpSocket and QUdpSocket
公共类型
BindFlag
- QAbstractSocket::ShareAddress
允许其他服务绑定到相同的地址和端口。当多个进程通过监听同一地址和端口来共享单个服务的负载时,这很有用(例如,具有多个预分叉监听器的web服务器可以大大缩短响应时间)。但是,由于允许重新绑定任何服务,因此此选项需要考虑某些安全因素。请注意,通过将此选项与ReuseAddressHint结合使用,您还将允许您的服务重新绑定现有的共享地址。在Unix上,这相当于SO_REUSEADDR套接字选项。在Windows上,这是默认行为,因此忽略此选项。
- QAbstractSocket::DontShareAddress
以独占方式绑定地址和端口,这样就不允许其他服务重新绑定。通过将此选项传递给QAbstractSocket::Bind(),您可以保证在成功时,您的服务是唯一一个监听地址和端口的服务。即使服务传递了ReuseAddressHint,也不允许重新绑定。此选项提供了比ShareAddress更高的安全性,但在某些操作系统上,它要求您以管理员权限运行服务器。在Unix和macOS上,不共享是绑定地址和端口的默认行为,因此忽略此选项。在Windows上,此选项使用SO_EXCLUSIVEADDRUSE套接字选项。
- QAbstractSocket::ReuseAddressHint
向QAbstractSocket提供提示,即使地址和端口已被另一个套接字绑定,它也应尝试重新绑定服务。在Windows和Unix上,这相当于SO_REUSEADDR套接字选项。
- QAbstractSocket::DefaultForPlatform
当前平台的默认选项。在Unix和macOS上,这相当于(DontShareAddress+ReuseAddressHint),在Windows上,它相当于ShareAddress。
NetworkLayerProtocol
指定网络层协议
PauseModes
描述什么时候 应该暂停数据传输
当前只支持此枚举描述了套接字在继续数据传输时应该停止的行为。目前唯一支持的通知是QSslSocket::sslErrors()。
SocketError
此枚举描述了可能发生的套接字错误。
- QAbstractSocket::ConnectionRefusedError
连接被拒绝或者超时 - QAbstractSocket::RemoteHostClosedError
远程主机关闭了连接。请注意,在发送远程关闭通知后,客户端套接字(即此套接字)将被关闭。 - QAbstractSocket::HostNotFoundError
The host address was not found. - QAbstractSocket::SocketAccessError
套接字操作失败,因为应用程序缺乏所需的权限。 - QAbstractSocket::SocketResourceError
本地系统资源不足(例如,套接字太多)。 - QAbstractSocket::SocketTimeoutError
套接字操作超时。 - QAbstractSocket::DatagramTooLargeError
数据报大于操作系统的限制(可能低至8192字节)。 - QAbstractSocket::NetworkError
网络发生错误(例如,网络电缆意外拔出)。 - QAbstractSocket::AddressInUseError
为QAbstractSocket::bind()指定的地址已在使用中,并设置为独占。 - QAbstractSocket::SocketAddressNotAvailableError
为QAbstractSocket::bind()指定的地址不属于主机。 - QAbstractSocket::UnsupportedSocketOperationError
本地操作系统不支持请求的套接字操作(例如,缺乏IPv6支持)。 - QAbstractSocket::ProxyAuthenticationRequiredError
套接字正在使用代理,代理需要身份验证。 - QAbstractSocket::SslHandshakeFailedError
SSL/TLS握手失败,因此连接已关闭(仅在QSslSocket中使用) - QAbstractSocket::UnfinishedSocketOperationError
仅由QAbstractSocketEngine使用,最后一次尝试的操作尚未完成(仍在后台进行) - QAbstractSocket::ProxyConnectionRefusedError
无法联系代理服务器,因为与该服务器的连接被拒绝 - QAbstractSocket::ProxyConnectionClosedError
与代理服务器的连接意外关闭(在建立与最终对等方的连接之前) - QAbstractSocket::ProxyConnectionTimeoutError
与代理服务器的连接超时或代理服务器在身份验证阶段停止响应。 - QAbstractSocket::ProxyNotFoundError
找不到使用setProxy()设置的代理地址(或应用程序代理) - QAbstractSocket::ProxyProtocolError
与代理服务器的连接协商失败,因为无法理解来自代理服务器的响应 - QAbstractSocket::OperationError
当套接字处于不允许的状态时,尝试了一个操作 - QAbstractSocket::SslInternalError
正在使用的SSL库报告了一个内部错误。这可能是由于库安装错误或配置错误造成的 - QAbstractSocket::SslInvalidUserDataError
提供的数据(证书、密钥、密码等)无效,使用这些数据导致SSL库中出现错误。 - QAbstractSocket::TemporaryError
出现临时错误(例如,操作将被阻止,套接字未被阻止)。 - QAbstractSocket::UnknownSocketError
An unidentified error occurred.
SocketOption
此枚举表示可以在套接字上设置的选项。如果需要,可以在从套接字接收到connected()信号后或从QTcpServer接收到新套接字后设置它们。
- QAbstractSocket::LowDelayOption
尝试优化套接字以实现低延迟。对于QTcpSocket,这将设置TCP_NODELAY选项并禁用Nagle算法。将其设置为1以启用。 - QAbstractSocket::KeepAliveOption
保持长连接 - QAbstractSocket::MulticastTtlOption
将其设置为整数值,以设置IP_MULTICAST_TTL(用于多播数据报的TTL)套接字选项。 - QAbstractSocket::MulticastLoopbackOption
将其设置为1以启用IP_MULTICAST_LOOP(多播环回)套接字选项。 - QAbstractSocket::TypeOfServiceOption
Windows不支持此选项。这映射到IP_TOS套接字选项。有关可能的值,请参阅下表 - QAbstractSocket::SendBufferSizeSocketOption
在操作系统级别设置套接字发送缓冲区大小(以字节为单位)。这映射到SO_SNDBUF套接字选项。此选项不影响QIODevice或QAbstractSocket缓冲区。Qt 5.3中引入了此枚举值 - QAbstractSocket::ReceiveBufferSizeSocketOption
在操作系统级别设置套接字接收缓冲区大小(以字节为单位)。这映射到SO_RCVBUF套接字选项。此选项不会影响QIODevice或QAbstractSocket缓冲区(请参阅setReadBufferSize())。Qt 5.3中引入了此枚举值。 - QAbstractSocket::PathMtuSocketOption
检索IP堆栈当前已知的路径最大传输单元(PMTU)值(如果有)。一些IP栈还允许设置传输的MTU。这个枚举值是在Qt 5.11中引入的
TypeOfServiceOption 可能的值为:
224
Network control
192
Internetwork control
160
CRITIC/ECP
128
Flash override
96
Flash
64
Immediate
32
Priority
0
Routine
SocketState
socket当前的状态
QAbstractSocket::UnconnectedState
未连接状态
QAbstractSocket::HostLookupState
套接字正在执行主机名查找。
QAbstractSocket::ConnectingState
连接中状态
QAbstractSocket::ConnectedState
已连接状态
QAbstractSocket::BoundState
套接字绑定到地址和端口
QAbstractSocket::ClosingState
断开连接的状态
QAbstractSocket::ListeningState
监听状态 (仅供内部使用)。
SocketType
公共函数
void abort()
中止当前连接并重置套接字。与disconnectFromHost()不同,此函数会立即关闭套接字,丢弃写缓冲区中的所有挂起数据。
bool bind(const QHostAddress &address, quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
使用BindMode模式绑定到端口上的地址。
对于UDP套接字,绑定后,每当UDP数据报到达指定的地址和端口时,都会发出信号QUdpSocket::readyRead()。因此,此函数对于编写UDP服务器很有用。
对于TCP套接字,此函数可用于指定用于传出连接的接口,这在多个网络接口的情况下很有用。
默认情况下,使用DefaultForPlatform BindMode绑定套接字。如果未指定端口,则选择随机端口。
成功后,函数返回true,套接字进入BoundState;否则返回false。
bool bind(quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
这是一个重载函数。
绑定到QHostAddress:使用BindMode模式的任何端口上端口。
默认情况下,使用DefaultForPlatform BindMode绑定套接字。如果未指定端口,则选择随机端口。
virtual void connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocol protocol = AnyIPProtocol)
尝试在给定端口上连接到hostName。协议参数可用于指定要使用的网络协议(例如IPv4或IPv6)。
套接字在给定的openMode中打开,首先进入HostLookupState,然后执行hostName的主机名查找。如果查找成功,则发出hostFound(),QAbstractSocket进入ConnectingState。然后,它尝试连接到查找返回的一个或多个地址。最后,如果建立了连接,QAbstractSocket将进入ConnectedState并发出connected()。
在任何时候,套接字都可以发出errorCoccurred()来表示发生了错误。
hostName可以是字符串形式的IP地址(例如“43.195.83.32”),也可以是主机名(例如“example.com”)。QAbstractSocket仅在需要时进行查找。端口采用本机字节顺序。
void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite)
尝试连接到指定的地址和端口上
[virtual] void QAbstractSocket::disconnectFromHost()
尝试关闭插座。如果有待写入的数据,QAbstractSocket将进入ClosingState并等待所有数据写入。最终,它将进入UnconnectedState并发出disconnected()信号。
QAbstractSocket::SocketError QAbstractSocket::error() const
返回上次发生的错误类型。
bool QAbstractSocket::flush()
此函数尽可能多地从内部写缓冲区写入底层网络套接字,而不会造成阻塞。如果写入了任何数据,此函数将返回true;否则返回false。
如果您需要QAbstractSocket立即开始发送缓冲数据,请调用此函数。成功写入的字节数取决于操作系统。在大多数情况下,您不需要调用此函数,因为一旦控件返回事件循环,QAbstractSocket将自动开始发送数据。在没有事件循环的情况下,改为调用waitForBytesWriten()。
[override virtual] bool QAbstractSocket::isSequential() const
如果此设备是连续的,则返回true;否则返回false。
与随机存取设备不同,顺序设备没有开始、结束、大小或当前位置的概念,也不支持查找。只有当设备报告数据可用时,您才能从设备读取。顺序设备最常见的例子是网络套接字。在Unix上,/dev/zero和fifo管道等特殊文件是顺序的。
另一方面,常规文件确实支持随机访问。它们既有大小又有当前位置,还支持在数据流中前后查找。常规文件是不连续的。
继承自父类
QIODevice::isSequential()
bool QAbstractSocket::isValid() const
如果套接字有效并准备好使用,则返回true;否则返回false。
QHostAddress QAbstractSocket::localAddress() const
返回本地套接字的主机地址(如果可用);否则返回QHostAddress::Null。
这通常是主机的主IP地址,但也可以是QHostAddress::LocalHost(127.0.0.1)用于连接到本地主机。
quint16 QAbstractSocket::localPort() const
返回本地套接字的主机端口号(按本机字节顺序)(如果可用);否则返回0。
QHostAddress QAbstractSocket::peerAddress() const
如果套接字处于ConnectedState状态,则返回连接对等端的地址;否则返回QHostAddress::Null。
QString QAbstractSocket::peerName() const
返回connectToHost()指定的对等方的名称,或者如果未调用connectToHosts(),则返回空的QString。
quint16 QAbstractSocket::peerPort() const
如果套接字处于ConnectedState状态,则返回已连接对等端的端口;否则返回0。
QString QAbstractSocket::protocolTag() const
返回此套接字的协议标记。如果设置了协议标签,则在内部创建QNetworkProxyQuery时,会将其传递给QNetworkProxyQuery,以指示要使用的协议标签。
QNetworkProxy QAbstractSocket::proxy() const
返回此套接字的网络代理。默认情况下,使用QNetworkProxy::DefaultProxy,这意味着此套接字将查询应用程序的默认代理设置。
qint64 QAbstractSocket::readBufferSize() const
返回内部读取缓冲区的大小。这限制了客户端在调用read()或readAll()之前可以接收的数据量。
读取缓冲区大小为0(默认值)意味着缓冲区没有大小限制,确保没有数据丢失。
[override virtual protected] qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
从设备读取最多maxSize字节的数据,并返回读取的字节数,如果发生错误,则返回-1。
如果没有要读取的字节,并且永远不会有更多的字节可用(例如套接字关闭、管道关闭、子进程完成),则此函数返回-1。
此函数由QIODevice调用。在创建QIODevice的子类时重新实现此函数。
重新实现此函数时,此函数在返回之前读取所有必需的数据非常重要。为了使QDataStream能够对类进行操作,这是必需的。QDataStream假设所有请求的信息都已读取,因此如果出现问题,不会重试读取。
此函数可能在maxSize为0时调用,可用于执行读取后操作。
[override virtual protected] qint64 QAbstractSocket::readLineData(char *data, qint64 maxlen)
将最多maxSize个字符读取到数据中,并返回读取的字符数。
此函数由readLine()调用,并使用getChar()提供其基本实现。缓冲设备可以通过重新实现此函数来提高readLine()的性能。
readLine()在数据后附加一个“\0”字节;readLineData()不需要这样做。
如果重新实现此函数,请注意返回正确的值:它应该返回此行中读取的字节数,包括终止换行符,或者如果此时没有要读取的行,则返回0。如果发生错误,只有在没有读取字节的情况下,它才应该返回-1。读取过去的EOF被认为是一个错误。
[virtual] void QAbstractSocket::resume()
继续在套接字上传输数据。此方法仅应在套接字设置为在收到通知时暂停并收到通知后使用。目前唯一支持的通知是QSslSocket::sslErrors()。如果套接字未暂停,则调用此方法会导致未定义的行为。
[virtual] bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = ConnectedState, QIODevice::OpenMode openMode = ReadWrite)
使用本机套接字描述符socketDescriptor初始化QAbstractSocket。如果socketDescriptor被接受为有效的套接字描述符,则返回true;否则返回false。套接字以openMode指定的模式打开,并进入socketState指定的套接字状态。读写缓冲区被清除,丢弃任何未决数据。
注意:不可能用相同的本机套接字描述符初始化两个抽象套接字。
[protected] void QAbstractSocket::setSocketError(QAbstractSocket::SocketError socketError)
重新实现:QIODevice::waitForBytesWrited(int msecs)。
此函数会一直阻塞,直到套接字上至少写入了一个字节,并且发出了bytesWriten()信号。该函数将在毫秒后超时;默认超时为30000毫秒。
如果发出bytesWriten()信号,则函数返回true;否则,它将返回false(如果发生错误或操作超时)。
注意:此功能在Windows上可能会随机失败。如果您的软件将在Windows上运行,请考虑使用事件循环和bytesWriten()信号。
[virtual] bool QAbstractSocket::waitForConnected(int msecs = 30000)
等待套接字连接,最长毫秒。如果连接已建立,则此函数返回true;否则返回false。如果返回false,您可以调用error()来确定错误的原因。
以下示例等待连接建立最多一秒钟:
socket->connectToHost(“imap”,143);
if(套接字->waitForConnected(1000))
qDebug(“已连接!”);
如果msecs为-1,则此函数不会超时。
注意:此函数的等待时间可能略长于毫秒,具体取决于完成主机查找所需的时间。
注意:多次调用此函数不会累积时间。如果函数超时,连接过程将中止。
注意:此功能在Windows上可能会随机失败。如果您的软件将在Windows上运行,请考虑使用事件循环和connected()信号
[virtual] bool QAbstractSocket::waitForDisconnected(int msecs = 30000)
等待套接字断开连接,最长毫秒。如果连接已成功断开,则此函数返回true;否则,它将返回false(如果操作超时、发生错误或此QAbstractSocket已断开连接)。如果返回false,您可以调用error()来确定错误的原因。
以下示例等待连接关闭最多一秒钟:
socket->disconnectFromHost();
if (socket->state() == QAbstractSocket::UnconnectedState
|| socket->waitForDisconnected(1000)) {
qDebug("Disconnected!");
}
如果msecs为-1,则此函数不会超时。
注意:此功能在Windows上可能会随机失败。如果您的软件将在Windows上运行,请考虑使用事件循环和disconnected()信号。
bool QAbstractSocket::waitForReadyRead(int msecs = 30000)
重新实现:QIODevice::waitForReadyRead(int毫秒)。
此函数会一直阻塞,直到有新数据可供读取并且发出readyRead()信号。该函数将在毫秒后超时;默认超时为30000毫秒。
如果发出readyRead()信号并且有新的数据可供读取,则函数返回true;否则,它将返回false(如果发生错误或操作超时)。
注意:此功能在Windows上可能会随机失败。如果您的软件将在Windows上运行,请考虑使用事件循环和readyRead()信号。
[override virtual protected] qint64 QAbstractSocket::writeData(const char *data, qint64 size)
将数据写入设备的最大字节数。返回写入的字节数,如果发生错误,则返回-1。
此函数由QIODevice调用。在创建QIODevice的子类时重新实现此函数。
重新实现此函数时,此函数在返回之前写入所有可用数据非常重要。为了使QDataStream能够对类进行操作,这是必需的。QDataStream假设所有信息都已写入,因此如果出现问题,不会重试写入。