QT基础(18)- QAbstractSocket
QT基础(18)- QAbstractSocket
- 1 创建简单的客户端
- 2 QAbstractSocket
- 2.1 简介
- 2.2 枚举
- 2.2.1 BingFlag
- 2.2.2 NetworkLayerProtocol
- 2.2.3 PauseMode
- 2.2.4 SocketError
- 2.2.5 SocketOption
- 2.2.6 SocketType
- 2.2.7 SocketState
- 2.3 公有函数
- 2.3.1 构造函数
- 2.3.2 abort
- 2.3.3 bind
- 2.3.4 connectToHost
- 2.3.5 disconnectFromHost
- 2.3.6 error
- 2.3.7 flush
- 2.3.8 isValid
- 2.3.9 localAddress
- 2.3.10 localPort
- 2.3.11 pauseMode()
- 2.3.12 peerAddress
- 2.3.13 peerName
- 2.3.14 peerPort
- 2.3.15 protocolTag
- 2.3.16 proxy
- 2.3.17 resume
- 2.3.18 setPauseMode
- 2.3.19 setProtocolTag
- 2.3.20 readBufferSize
- 2.3.21 setReadBufferSize
- 2.3.22 setSocketDescriptor
- 2.3.23 setSocketOption
- 2.3.24 socketType
- 2.3.25 state
- 2.3.26 waitForConnected
- 2.3.27 waitForDisconnected
- 2.4 从父类中(QIODevice)重新实现的函数
- 2.4.1 atEnd
- 2.4.2 bytesAvailable
- 2.4.5 bytesWrite
- 2.4.6 canReadLine
- 2.4.7 close
- 2.4.8 isSequential
- 2.4.9 waitForBytesWritten
- 2.4.10 waitForReadyRead
- 2.5 信号
- `void connected()`
- `void disconnected()`
- `void errorOccurred(QAbstractSocket::SocketError socketError)`
- `void hostFound()`
- `void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)`
- `void stateChanged(QAbstractSocket::SocketState socketState)`
- 2.6 受保护的函数
- `void setLocalAddress(const QHostAddress &address)`
- `void setLocalPort(quint16 port)`
- `void setPeerAddress(const QHostAddress &address)`
- `void setPeerName(const QString &name)`
- `void setPeerPort(quint16 port)`
- `void setSocketError(QAbstractSocket::SocketError socketError)`
- `void setSocketState(QAbstractSocket::SocketState state)`
- 2.7 重新实现的保护函数
- `virtual qint64 readData(char *data, qint64 maxSize) override`
- `virtual qint64 readLineData(char *data, qint64 maxlen) override`
- `virtual qint64 writeData(const char *data, qint64 size) override`
1 创建简单的客户端
要建立一个TCP客户端其实是很容易的一般需要一下几步
- 包含QTcpSocket头文件:
#include <QTcpSocket>
- 创建QTcpSocket对象:
QTcpSocket* socket = new QTcpSocket(this);
- 连接服务器:
socket->connectToHost("192.168.1.106", 6000);
这里使用connectToHost函数连接服务器。如果连接成功,QTcpSocket会发出connected()信号;如果连接失败,会发出error()信号。
- 处理连接结果:
if(socket->waitForConnected()){// 连接成功
} else {// 连接失败
}
waitForConnected会阻塞进程
- 发送数据:
QString dataStr = "Hello";
socket->write(dataStr.toUtf8());
- 接收数据:
connect(socket, &QTcpSocket::readyRead, this, [&](){QByteArray data = socket->readAll();// 处理接收到的数据
});
使用readyRead()信号接收数据,然后使用readAll()函数读取接收到的数据。注意,readyRead()信号可能会被多次触发,所以要使用while循环读取所有数据。
- 断开连接:
socket->disconnectFromHost();
使用disconnectFromHost()函数断开与服务器的连接。
2 QAbstractSocket
2.1 简介
以下内容来自官方,本人认为已经讲解的非常清晰明了:
QAbstractSocket是QTcpSocket和QUdpSocket的基类,包含这两个类的所有共同功能。如果需要使用套接字,可以选择以下两种方式:
- 实例化QTcpSocket或QUdpSocket。
- 创建原生套接字描述符,实例化QAbstractSocket,并调用setSocketDescriptor()函数将原生套接字包装起来。
TCP(传输控制协议)是一种可靠的、面向流的、面向连接的传输协议。UDP(用户数据报协议)是一种不可靠的、面向数据报的、无连接的协议。实际上,这意味着TCP更适合于连续传输数据,而更轻量级的UDP可以在可靠性不重要的情况下使用。
QAbstractSocket的API统一了这两种协议之间的大部分差异。例如,虽然UDP是无连接的,但connectToHost()函数为UDP套接字建立了一个虚拟连接,使得可以使用QAbstractSocket在底层协议不同的情况下使用相同的方式。在内部,QAbstractSocket会记住传递给connectToHost()的地址和端口号,并使用这些值来执行read()和write()等函数。
在任何时候,QAbstractSocket都有一个状态(通过state()函数返回)。初始状态是UnconnectedState。在调用connectToHost()之后,套接字首先进入HostLookupState状态。如果找到主机,QAbstractSocket进入ConnectingState状态并发出hostFound()信号。当连接建立后,它进入ConnectedState状态并发出connected()信号。如果在任何阶段出现错误,则发出errorOccurred()信号。每当状态发生变化时,都会发出stateChanged()信号。为方便起见,isValid()函数返回套接字是否准备好读写,但是请注意,在读写之前,套接字的状态必须是ConnectedState。
通过调用read()或write()函数读取或写入数据,或使用readLine()和readAll()等方便函数。QAbstractSocket还从QIODevice继承了getChar()、putChar()和ungetChar(),可以用于单字节。当数据已写入套接字时,将发出bytesWritten()信号。请注意,Qt不限制写缓冲区大小。可以通过侦听此信号来监视其大小。
每次新的数据块到达时,将发出readyRead()信号。然后,bytesAvailable()返回可供读取的字节数。通常,会将readyRead()信号连接到槽,并在那里读取所有可用的数据。如果没有一次读取所有数据,则剩余的数据仍将在稍后可用,并且任何新的传入数据将附加到QAbstractSocket的内部读取缓冲区中。要限制读取缓冲区的大小,请调用setReadBufferSize()。
要关闭套接字,请调用disconnectFromHost()函数。QAbstractSocket进入QAbstractSocket::ClosingState状态。在所有挂起的数据都写入套接字后,QAbstractSocket实际上关闭套接字,进入QAbstractSocket::UnconnectedState状态,并发出disconnected()信号。如果要立即中止连接,并放弃所有挂起的数据,请调用abort()函数。如果远程主机关闭了连接,则QAbstractSocket将发出errorOccurred(QAbstractSocket::RemoteHostClosedError)信号,在此期间,套接字状态仍为ConnectedState,然后发出disconnected()信号。
已连接对等体的端口和地址可以通过调用peerPort()和peerAddress()函数获取。peerName()函数返回传递给connectToHost()的对等体主机名。localPort()和localAddress()返回本地套接字的端口和地址。
QAbstractSocket提供了一组函数,可以暂停调用线程,直到某些信号被发出。可以使用这些函数来实现阻塞套接字:
waitForConnected()函数会阻塞,直到建立连接。
waitForReadyRead()函数会阻塞,直到有新数据可供读取。
waitForBytesWritten()函数会阻塞,直到一次有效载荷的数据已写入套接字。
waitForDisconnected()函数会阻塞,直到连接关闭。
我们以一个示例来说明:
int numRead = 0, numReadTotal = 0;
char buffer[50];while (true) {numRead = socket.read(buffer, 50);// 对数组做处理numReadTotal += numRead;if (numRead == 0 && !socket.waitForReadyRead()) {break;}
}
如果waitForReadyRead()返回false,则连接已关闭或发生错误。
使用阻塞套接字的编程与使用非阻塞套接字的编程有根本的不同。阻塞套接字不需要事件循环,通常导致代码更简单。然而,在GUI应用程序中,应该只在非GUI线程中使用阻塞套接字,以避免冻结用户界面。有关两种方法的概述,请参见fortuneclient和blockingfortuneclient示例。
注意:我们不建议将阻塞函数与信号一起使用。应该使用这两种可能性之一。
QAbstractSocket可以与QTextStream和QDataStream的流运算符(operator<<()和operator>>())一起使用。但是,需要注意一个问题:在尝试使用operator>>()读取数据之前,必须确保有足够的数据可用。
QAbstractSocket是一个抽象类,不能直接创建对象。它被用作QTcpSocket和QUdpSocket的基类,以提供这两个类的公共功能
2.2 枚举
2.2.1 BingFlag
用于在绑定套接字时指定绑定选项
2.2.2 NetworkLayerProtocol
用于指定套接字使用的网络层协议
2.2.3 PauseMode
2.2.4 SocketError
2.2.5 SocketOption
QAbstractSocket::SocketOption枚举类型表示可在套接字上设置的选项。在收到与套接字建立连接的connected()信号或从QTcpServer接收到新套接字之后,可以设置这些选项。
常量 | 描述 |
---|---|
QAbstractSocket::LowDelayOption | 尝试优化套接字以实现低延迟。对于QTcpSocket,这将设置TCP_NODELAY选项并禁用Nagle算法。将其设置为1以启用。QAbstractSocket::LowDelayOption是一个用于优化套接字以实现低延迟的选项。对于QTcpSocket来说,设置此选项会启用TCP_NODELAY选项,并禁用Nagle算法,这些都可以减少套接字数据传输时的延迟。这在需要实时数据传输的应用程序中非常有用,如在线游戏或视频流。在这些应用程序中,即使少量的延迟也可能导致用户体验的显著下降。因此,通过设置此选项可以使套接字优化其行为,以便实现更低的延迟。 |
QAbstractSocket::KeepAliveOption | 将此设置为1以启用SO_KEEPALIVE套接字选项。QAbstractSocket::KeepAliveOption是一个套接字选项,用于启用/禁用套接字上的SO_KEEPALIVE功能。启用此选项后,操作系统将定期检查套接字连接的对端是否仍然存在。如果发现对端不存在,操作系统将关闭套接字连接,并且可以触发一个连接断开的信号。这可以帮助检测连接断开的情况,例如在无法及时处理网络连接时,可能会发生应用程序崩溃等情况。但是,应该注意,启用此选项会在套接字上引入一定的开销,因此不应该在不需要时启用它,以免浪费资源。 |
QAbstractSocket::MulticastTtlOption | 将此值设置为整数值以设置IP_MULTICAST_TTL(组播数据报的TTL)套接字选项。QAbstractSocket::MulticastTtlOption是一个套接字选项,用于设置多播数据报的TTL(生存时间)。TTL是一个整数值,表示多播数据报可以被转发的最大次数。每次多播数据报从一个路由器传递到另一个路由器时,其TTL值都会减少1。当TTL值减为0时,多播数据报将被丢弃。通过设置此选项,你可以控制多播数据报的传递范围,从而避免不必要的网络流量或确保多播数据报只在局域网内传递。这对于一些需要向多个计算机广播信息的应用程序非常有用,如视频流或在线游戏。 |
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中引入的。 |
2.2.6 SocketType
常量 | 描述 |
---|---|
QAbstractSocket::TcpSocket | TCP套接字。 |
QAbstractSocket::UdpSocket | UDP套接字。 |
QAbstractSocket::SctpSocket | SCTP套接字(从Qt 5.12开始支持)。 |
QAbstractSocket::UnknownSocketType | 除了TCP,UDP和SCTP |
2.2.7 SocketState
enum QAbstractSocket::SocketState
常量 | 描述 |
---|---|
QAbstractSocket::UnconnectedState | 未连接状态 |
QAbstractSocket::HostLookupState | 正在查找主机状态 |
QAbstractSocket::ConnectingState | 正在连接状态 |
QAbstractSocket::ConnectedState | 已连接状态 |
QAbstractSocket::BoundState | 已绑定状态 |
QAbstractSocket::ClosingState | 正在关闭状态 |
QAbstractSocket::ListeningState | 监听状态 |
2.3 公有函数
2.3.1 构造函数
QAbstractSocket::QAbstractSocket(QAbstractSocket::SocketType socketType, QObject *parent)
参数socketType指定套接字的类型(参考2.2.6)
参数parent是可选的,指定该对象的父对象。默认值为nullptr。
QAbstractSocket是一个抽象类,不能直接创建对象。它被用作QTcpSocket和QUdpSocket的基类,以提供这两个类的公共功能。
2.3.2 abort
void QAbstractSocket::abort()
QAbstractSocket::abort()是一个公共函数,用于立即终止套接字上的任何当前操作,并关闭套接字。与disconnectFromHost()不同,abort()不会等待套接字上的缓冲区被刷新或任何未完成的操作完成。它会立即关闭套接字连接并发出disconnected()信号,这可能会导致丢失未发送或未接收的数据。通常,应在需要尽快关闭套接字连接的情况下使用此函数,例如在用户主动关闭应用程序或发生错误时。
2.3.3 bind
bool QAbstractSocket::bind(const QHostAddress &address, quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
QAbstractSocket::bind()函数是用于在本地套接字上绑定地址和端口的公共函数。它接受三个参数,其中第一个参数是一个QHostAddress类型的对象,表示要绑定的IP地址;第二个参数是一个整数,表示要绑定的端口号;第三个参数是一个枚举类型的值,表示要使用的绑定模式,默认值为DefaultForPlatform。
如果未指定端口号,则系统会为套接字分配一个可用端口。如果绑定成功,则返回true,否则返回false。
该函数用于将套接字绑定到指定的地址和端口,其中的BindMode参数表示绑定模式。对于UDP套接字,绑定后,每当UDP数据报到达指定的地址和端口时,都会发出QUdpSocket::readyRead()信号。因此,该函数对编写UDP服务器很有用。对于TCP套接字,此函数可用于指定用于传出连接的接口,这在存在多个网络接口的情况下非常有用。默认情况下,使用DefaultForPlatform BindMode绑定套接字。如果未指定端口,则选择随机端口。如果成功绑定,则函数返回,并且套接字进入BoundState;否则返回false。该函数在
bool bind(quint16 port = 0, QAbstractSocket::BindMode mode = DefaultForPlatform)
这是一个重载函数。
该函数将套接字绑定到QHostAddress::Any地址和指定的端口,其中的BindMode参数表示绑定模式。QHostAddress::Any表示该套接字将绑定到所有可用网络接口的地址。默认情况下,使用DefaultForPlatform BindMode绑定套接字。如果未指定端口,则选择随机端口。如果成功绑定,则函数返回,并且套接字进入BoundState;否则返回false。
2.3.4 connectToHost
virtual void connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode = ReadWrite, QAbstractSocket::NetworkLayerProtocol protocol = AnyIPProtocol)
该函数用于在TCP模式下连接到远程主机。它将套接字连接到主机名为hostName和端口为port的远程主机。其中openMode参数表示打开模式,可设置为ReadWrite(默认值)或ReadOnly。NetworkLayerProtocol参数protocol表示连接使用的网络协议,默认值为AnyIPProtocol,表示Qt将自动选择最佳协议。
如果连接成功,则QTcpSocket将发出connected()信号,可以在连接成功后读写套接字。如果连接失败,则发出errorOccurred()信号。在连接期间,QAbstractSocket处于ConnectingState状态。
virtual void connectToHost(const QHostAddress &address, quint16 port, QIODevice::OpenMode openMode = ReadWrite)
该函数用于在TCP模式下连接到远程主机。它将套接字连接到指定地址为address和端口为port的远程主机。其中openMode参数表示打开模式,可设置为ReadWrite(默认值)或ReadOnly。
如果连接成功,则QTcpSocket将发出connected()信号,可以在连接成功后读写套接字。如果连接失败,则发出errorOccurred()信号。在连接期间,QAbstractSocket处于ConnectingState状态。
2.3.5 disconnectFromHost
void QAbstractSocket::disconnectFromHost()
该函数用于断开与主机的连接,关闭套接字并将QAbstractSocket的状态设置为UnconnectedState。当与主机的连接被断开并且所有待处理的数据已经被传输时,将发出disconnected()信号。如果套接字未连接,则函数什么也不做。
***与close()函数不同,disconnectFromHost()不会立即关闭套接字,而是等待所有数据传输完成。***可以使用waitForDisconnected()函数阻塞,直到套接字已经断开连接。在断开连接之前,还可以使用abort()函数强制断开连接并立即关闭套接字。
2.3.6 error
QAbstractSocket::SocketError QAbstractSocket::error() const
QAbstractSocket::error()是一个成员函数,用于返回上一次发生的错误类型。当连接建立时,可以通过调用此函数获取连接是否成功。当连接断开或发生错误时,此函数也可以用于获取错误类型。QAbstractSocket::SocketError是一个枚举类型,表示可能发生的错误类型,例如连接被拒绝、连接超时、远程主机关闭连接等。在调用此函数之前,必须先连接errorOccurred()信号,以便在发生错误时及时处理。
QAbstractSocket::SocketError见2.2.4
errorString()可以描述错误的字符串
2.3.7 flush
bool QAbstractSocket::flush()
flush() 函数用于强制将写缓冲区中的数据写入套接字。该函数返回 true 表示写缓冲区的所有数据已成功写入套接字,否则返回 false。
如果您使用的是 QTcpSocket 或 QUdpSocket 类,则 flush() 函数会立即将数据写入网络。如果您使用的是其它类型的套接字,则该函数只是将数据写入内核的套接字缓冲区,而不是立即写入网络。写入网络的时间可能会受到许多因素的影响,例如网络拥塞、远程主机的可用性等。
2.3.8 isValid
bool QAbstractSocket::isValid() const
QAbstractSocket::isValid()函数返回一个布尔值,指示当前套接字是否可用于读取和写入数据。如果套接字已连接且没有发生错误,则返回true;否则返回false。
在使用套接字之前,应该先检查套接字的有效性,以确保可以成功读写数据。如果套接字无效,则所有的读写操作都将失败。
2.3.9 localAddress
QHostAddress QAbstractSocket::localAddress() const
返回本地绑定的地址。在使用bind()函数绑定地址和端口之后,可以使用该函数获取本地地址。
如果尚未绑定套接字,则该函数将返回QHostAddress::Null。
2.3.10 localPort
quint16 QAbstractSocket::localPort() const
返回绑定的端口
2.3.11 pauseMode()
QAbstractSocket::PauseModes pauseMode() const
QAbstractSocket::PauseModes 是 QAbstractSocket 类的一个枚举值,它表示当前套接字的暂停模式。暂停模式包括 ReadPause 和 WritePause,它们分别表示套接字的读取和写入是否被暂停。在某些情况下,例如当套接字写入缓冲区已满时,套接字可能会自动暂停写入。可以通过调用 setReadPause() 和 setWritePause() 方法来手动设置套接字的暂停模式。使用 pauseMode() 方法可以查询当前暂停模式。
QAbstractSocket::PauseModes 见2.2.3
2.3.12 peerAddress
QHostAddress QAbstractSocket::peerAddress() const
该函数返回与套接字连接的对等端地址。对于TCP套接字,它返回对等端的IP地址;对于UDP套接字,它返回上次收到数据报的发送方的IP地址。如果该套接字没有连接,则返回QHostAddress::Null。
2.3.13 peerName
QString QAbstractSocket::peerName() const
QAbstractSocket::peerName()函数返回已连接套接字的对等端主机名称。如果没有连接,该函数将返回一个空字符串。
对于TCP套接字,这个名称是在connectToHost()函数中指定的主机名。对于UDP套接字,这个名称是在readDatagram()函数中接收到的数据报的源地址中解析出来的。
注意,peerName()函数只返回主机名,而不返回端口号。要获取对等端套接字的端口号,可以使用peerAddress()函数并检查其端口号。
2.3.14 peerPort
quint16 QAbstractSocket::peerPort() const
函数返回与此套接字连接的远程端口。如果套接字没有连接,则返回0。
例如,如果您使用QTcpSocket类连接到服务器并与服务器建立连接,则可以使用此函数获取远程服务器的端口。
2.3.15 protocolTag
QString QAbstractSocket::protocolTag() const
QString QAbstractSocket::protocolTag() const 返回用于此套接字的协议标记,如果未设置,则返回一个空字符串。
协议标记是一个字符串,它标识套接字的网络协议类型。该标记通常用于跨线程或跨网络传递套接字,以便在需要时可以轻松地重新创建套接字。
此函数适用于QTcpSocket、QUdpSocket和QSctpSocket。
注意,对于已连接的套接字,协议标记应始终为默认值。只有在套接字未连接时才应设置协议标记。
此函数是虚拟的,并且在子类中可以重新实现以提供特定于协议的标记。
2.3.16 proxy
QNetworkProxy QAbstractSocket::proxy() const
void setProxy(const QNetworkProxy &networkProxy)
QAbstractSocket::proxy()函数返回当前套接字的网络代理对象,用于与远程主机通信时使用的代理服务器。如果没有设置代理,则返回默认构造的QNetworkProxy对象。
常量 | 描述 |
---|---|
QNetworkProxy::NoProxy | 不使用代理 |
QNetworkProxy::DefaultProxy | 代理是根据使用setApplicationProxy 设置的应用程序代理确定的() |
QNetworkProxy::Socks5Proxy | Socks5代理 |
QNetworkProxy::HttpProxy | 使用 HTTP 透明代理 |
QNetworkProxy::HttpCachingProxy | 仅代理 HTTP 请求 |
QNetworkProxy::FtpCachingProxy | 仅代理 FTP 请求 |
2.3.17 resume
void QAbstractSocket::resume()
该函数用于恢复套接字的数据传输。如果调用了pause()暂停数据传输,则可以使用该函数来恢复数据传输。
注意,如果套接字已经是活动状态,则该函数不会起作用。
2.3.18 setPauseMode
void QAbstractSocket::setPauseMode(QAbstractSocket::PauseModes pauseMode)
该函数用于控制是否在接收到某些通知时暂停数据传输。其中pauseMode参数指定了在什么条件下套接字应该被暂停。目前支持的通知仅为QSslSocket::sslErrors()。如果设置为PauseOnSslErrors,则在套接字上的数据传输将被暂停,并需要通过调用resume()显式地重新启用。默认情况下,此选项设置为PauseNever。必须在连接到服务器之前调用此选项,否则将导致未定义的行为。
2.3.19 setProtocolTag
void QAbstractSocket::setProtocolTag(const QString &tag)
该函数为 QAbstractSocket 新增的函数,在 Qt 5.14 版本中引入。该函数用于设置协议标签,即标识使用的协议。通常情况下,Qt 网络库能够自动检测所使用的协议,但在某些情况下,如果有多种协议可以使用,就需要手动指定协议标签。例如,对于 QTcpSocket,可以通过调用此函数来设置 HTTP/1.1 或 HTTP/2。
2.3.20 readBufferSize
qint64 QAbstractSocket::readBufferSize() const
QAbstractSocket::readBufferSize()函数返回当前套接字接收缓冲区大小(以字节为单位)。默认值是0,表示使用系统默认值。
注意:这个函数返回的是套接字的缓冲区大小,不是已经接收到的数据的大小。要获取已经接收到的数据的大小,可以使用bytesAvailable()函数。
如果你想改变缓冲区大小,可以使用setReadBufferSize()函数。
2.3.21 setReadBufferSize
void QAbstractSocket::setReadBufferSize(qint64 size)
void QAbstractSocket::setReadBufferSize(qint64 size)函数用于设置QAbstractSocket的内部读取缓冲区大小为size字节。
如果将缓冲区大小限制为某个特定大小,则QAbstractSocket不会缓冲超过该大小的数据。特别地,缓冲区大小为0意味着读取缓冲区无限制,所有传入的数据都将被缓冲。这是默认值。
此选项在以下情况下很有用:如果您仅在特定时间点读取数据(例如,在实时流应用程序中),或者如果您希望保护套接字免受接收过多数据的影响,这可能会导致应用程序内存不足。
仅QTcpSocket使用QAbstractSocket的内部缓冲区;QUdpSocket根本不使用任何缓冲,而是依赖于操作系统提供的隐式缓冲。因此,在QUdpSocket上调用此函数没有任何效果。
2.3.22 setSocketDescriptor
virtual bool setSocketDescriptor(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = ConnectedState, QIODevice::OpenMode openMode = ReadWrite)
virtual qintptr socketDescriptor() const
将现有套接字的描述符设置为QAbstractSocket的描述符,同时将状态设置为socketState并打开openMode。
此函数可用于将现有的原始套接字或操作系统文件描述符与QAbstractSocket实例关联,从而使其能够使用Qt套接字接口。如果传递的socketDescriptor不是有效的套接字描述符,则此函数返回false,否则返回true。
该函数仅在Unix和Windows上受支持,并且需要使用qintptr类型的套接字描述符。在Windows上,使用强制类型转换将SOCKET类型转换为qintptr。
如果成功,则QAbstractSocket进入ConnectedState,否则进入UnconnectedState。默认情况下,打开模式为ReadWrite。
2.3.23 setSocketOption
virtual void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
virtual QVariant socketOption(QAbstractSocket::SocketOption option)
设置套接字选项。option 参数指定选项,value 参数指定选项值。这个函数可用于设置选项,例如 QAbstractSocket::LowDelayOption 和 QAbstractSocket::KeepAliveOption。
这个函数可以在任何时间调用,包括连接建立后和传输期间。但是,并非所有套接字实现都支持所有选项。如果尝试设置不支持的选项,则会发出 QAbstractSocket::SocketError 信号。
请注意,对于某些套接字选项,必须在连接到主机之前调用此函数。例如,要在连接到主机之前设置 QAbstractSocket::LowDelayOption 选项,则必须在调用 connectToHost() 函数之前调用 setSocketOption()。
如果值无效,则不会发出信号并返回 false。否则,返回 true。
此函数是虚函数,因此可以在继承 QAbstractSocket 类的任何子类中重新实现它以添加特定于协议或特定于实现的选项。
2.3.24 socketType
QAbstractSocket::SocketType socketType() const
QAbstractSocket::SocketType socketType() const 返回当前套接字的类型,可以是 UnknownSocketType,TcpSocket,或者 UdpSocket。可以使用 setSocketType() 函数设置套接字类型。
2.3.25 state
QAbstractSocket::SocketState QAbstractSocket::state() const
连接状态
2.3.26 waitForConnected
bool QAbstractSocket::waitForConnected(int msecs = 30000)
waitForConnected函数是阻塞式的函数,用于等待socket连接到主机。
函数会一直阻塞直到连接成功,或者超时,或者连接出错。
参数msecs表示最大等待时间(单位为毫秒),默认为30秒。如果在规定时间内连接成功,则函数返回true,否则返回false。在连接成功前,该函数不会返回。
2.3.27 waitForDisconnected
bool QAbstractSocket::waitForDisconnected(int msecs = 30000)
是一个阻塞函数,用于等待socket与主机的断开连接。该函数会一直阻塞直到socket断开连接或者等待时间超时。如果在规定时间内连接断开,该函数返回true,否则返回false。
该函数可以传入一个可选参数msecs,用于设置等待的超时时间,单位为毫秒,默认为30000毫秒(30秒)。如果等待时间超过了这个时间仍然没有收到断开连接的信号,函数就会返回false。
2.4 从父类中(QIODevice)重新实现的函数
2.4.1 atEnd
bool QAbstractSocket::atEnd() const
QAbstractSocket::atEnd()是QIODevice类的成员函数,用于判断当前输入缓冲区是否已读完。对于QAbstractSocket而言,该函数用于判断当前接收缓冲区是否为空。
如果当前接收缓冲区为空,该函数将返回true,否则返回false。
需要注意的是,atEnd()函数只是判断当前缓冲区是否为空,并不会从socket中读取任何数据。如果想要从socket中读取数据,需要调用read()或者readAll()等函数
2.4.2 bytesAvailable
qint64 QAbstractSocket::bytesAvailable() const
函数 bytesAvailable() 返回了当前 socket 缓冲区中可供读取的字节数量。如果在可读取的缓冲区中没有数据可用,则此函数返回 0。
2.4.5 bytesWrite
qint64 QAbstractSocket::bytesToWrite() const
QAbstractSocket::bytesToWrite()函数返回缓冲区中还未发送的数据字节数。对于TCP套接字,该函数返回缓冲区中还未被发送的字节数,对于UDP套接字,该函数返回尚未被接收的数据报数量。该函数通常用于实现流量控制和同步写操作,以确保在写入大量数据之前套接字缓冲区具有足够的空间,从而避免写入阻塞。
2.4.6 canReadLine
bool QAbstractSocket::canReadLine() const
bool QAbstractSocket::canReadLine() const 函数用于判断当前 QAbstractSocket 的输入缓冲区中是否已经存在一行完整的数据。在 QIODevice 中,一行数据是以行结束符(例如 \n 或者 \r\n)作为结尾的数据,canReadLine() 函数能够检测到是否存在这样的一行数据。如果存在,则返回 true,否则返回 false。
2.4.7 close
void QAbstractSocket::close()
void QAbstractSocket::close() 关闭套接字,使套接字进入UnconnectedState状态,并释放其所有资源。
当调用此函数时,套接字会尝试将所有未写入的数据发送到对等方,并关闭套接字。请注意,它并不等待所有数据都写入,而是在尽力而为后立即关闭套接字。
关闭套接字后,将不再发出readyRead()信号。任何尝试读取套接字的操作将返回-1,并将error()设置为QAbstractSocket::RemoteHostClosedError。在大多数操作系统上,包括Unix和Windows,另一端可以重用同一端口。
在QTcpSocket中,如果套接字进入ClosingState,则需要等待disconnected()信号才能在重新使用相同的QTcpSocket之前进行重新连接。
调用close()后,不能再调用connectToHost()或connectToServer()。
2.4.8 isSequential
bool QAbstractSocket::isSequential() const
isSequential()是QIODevice类中的一个函数,QAbstractSocket类是QIODevice类的子类,因此它也继承了这个函数。该函数用于判断设备是否以连续的方式传输数据。对于QAbstractSocket类来说,由于它是一个网络套接字,数据是通过网络发送和接收的,因此它不是一个连续的设备,isSequential()函数会返回false。
2.4.9 waitForBytesWritten
bool QAbstractSocket::waitForBytesWritten(int msecs = 30000)
QAbstractSocket::waitForBytesWritten()是一个阻塞函数,它会等待套接字缓冲区的数据被完全写入,或者直到超时时间msecs到达为止。
该函数返回true表示套接字缓冲区的数据已经被完全写入,返回false表示在超时时间内未完成写入。在返回false时,应用程序可以通过error()函数判断错误原因,例如超时、写入错误等。
2.4.10 waitForReadyRead
bool QAbstractSocket::waitForReadyRead(int msecs = 30000)
bool QAbstractSocket::waitForReadyRead(int msecs = 30000)函数会阻塞当前线程,直到有新数据可读,或者超时指定的时间。如果在超时时间内有新数据可读,则返回 true,否则返回 false。
该函数的参数 msecs 指定了最长的等待时间,单位为毫秒,默认为 30000 毫秒(30 秒)。如果设置为 -1,则表示一直等待,直到有新数据可读。
该函数一般用于同步读取数据的场景。对于异步读取数据,应当使用信号槽机制,通过连接 readyRead() 信号实现。
2.5 信号
void connected()
void disconnected()
void errorOccurred(QAbstractSocket::SocketError socketError)
void hostFound()
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
void stateChanged(QAbstractSocket::SocketState socketState)
函数 | 描述 |
---|---|
connected() | 连接建立时发送该信号。 |
disconnected() | 断开连接时发送该信号。 |
errorOccurred(QAbstractSocket::SocketError socketError) | 在发生错误时发送该信号,参数 socketError 是错误的类型。 |
hostFound() | 当 QAbstractSocket 开始查找主机时发送该信号。 |
proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) | 当需要进行代理身份验证时发送该信号,参数 proxy 是要使用的代理,参数 authenticator 是指向要使用的 QAuthenticator 的指针。 |
stateChanged(QAbstractSocket::SocketState socketState) | 当 socket 状态发生更改时发送该信号,参数 socketState 是新状态的值。 |
2.6 受保护的函数
void setLocalAddress(const QHostAddress &address)
void setLocalPort(quint16 port)
void setPeerAddress(const QHostAddress &address)
void setPeerName(const QString &name)
void setPeerPort(quint16 port)
void setSocketError(QAbstractSocket::SocketError socketError)
void setSocketState(QAbstractSocket::SocketState state)
函数 | 描述 |
---|---|
void setLocalAddress(const QHostAddress &address) | 设置本地 IP 地址。 |
void setLocalPort(quint16 port) | 设置本地端口号。 |
void setPeerAddress(const QHostAddress &address) | 设置对端 IP 地址。 |
void setPeerName(const QString &name) | 设置对端主机名。 |
void setPeerPort(quint16 port) | 设置对端端口号。 |
void setSocketError(QAbstractSocket::SocketError socketError) | 设置套接字的错误状态。 |
void setSocketState(QAbstractSocket::SocketState state) | 设置套接字的状态。 |
2.7 重新实现的保护函数
virtual qint64 readData(char *data, qint64 maxSize) override
virtual qint64 readLineData(char *data, qint64 maxlen) override
virtual qint64 writeData(const char *data, qint64 size) override
这些是 QAbstractSocket 类中的保护成员函数,其作用是重新实现父类的保护成员函数。这些函数包括:
readData():读取数据的函数,用于从 socket 中读取数据,必须在子类中重新实现;
readLineData():读取一行数据的函数,用于从 socket 中读取一行数据,必须在子类中重新实现;
writeData():写入数据的函数,用于向 socket 中写入数据,必须在子类中重新实现。
这些函数是保护成员函数,因此不能在 QAbstractSocket 的对象之外直接调用。而是必须在子类中重新实现,以便实现特定的功能。这些函数通常在 QTcpSocket 或 QUdpSocket 类中重新实现,以实现 TCP 或 UDP 协议的网络通信。
相关文章:
QT基础(18)- QAbstractSocket
QT基础(18)- QAbstractSocket1 创建简单的客户端2 QAbstractSocket2.1 简介2.2 枚举2.2.1 BingFlag2.2.2 NetworkLayerProtocol2.2.3 PauseMode2.2.4 SocketError2.2.5 SocketOption2.2.6 SocketType2.2.7 SocketState2.3 公有函数2.3.1 构造函数2.3.2 a…...
机器学习与目标检测作业:安装pytorch
机器学习与目标检测作业:安装pytorch一、 进入官网复制下载命令二、 下载的过程2.1 conda命令运行三、 测试pytorch是否安装成功安装pytorch教程 一、 进入官网复制下载命令 进入官网复制下载命令如下图所示 二、 下载的过程 下载的过程如下图所示 2.1 conda命令运…...
Android 源码中的 JNI,到底是如何使用的?
Linux下 JNI的使用学习 Android 其中涉及对 JNI 的使用;JNI的使用对于 Android 来说又是十分的重要和关键。那么到底 Java 到底是如何调用 C/C 的,下面是非常简单的计算器源码,只是用来熟悉JNI的基本语法,其中我自己碰到过的一个问…...
重磅新品 / 酷炫展品 / 强大生态,广和通玩转 MWC Barcelona 2023
2月27日,2023世界移动通信大会(MWC Barcelona 2023)在西班牙巴塞罗那正式开幕。全球知名移动运营商、设备制造商、技术提供商、物联网企业齐聚一堂,以领先的技术、创新的场景、前瞻的洞察向全行业输送最新鲜的行业观点。作为全球领…...
Hbuilder+uniapp 从零开始创建一个小程序
当你看到这篇博客的时候,那~说明~我的这篇博客写完了……哈哈哈哈哈哈哈哈。好的,清耐心往下看哈。如果有需要的,可以关注一下小作,后面还有小程序的云开发嗷~一、申请一个小程序账号(已经有账号的小可爱可以跳过&…...
亚商投资顾问早餐FM/0303支持新能源汽车消费
01/亚商投资顾问早间导读高层调研集成电路企业并主持召开座谈会商务部:今年将积极出台新政策措施支持新能源汽车消费商务部:推动农村消费进一步恢复和扩大更好助力乡村振兴干细胞应用接连获重大突破机构密集调研相关上市公司02/亚商投资顾问新闻早餐// 热…...
Spring Boot 整合分布式缓存 Memcached
Memcached是一个开源、高性能,将数据分布于内存中并使用key-value存储结构的缓存系统。它通过在内存中缓存数据来减少向数据库的频繁访问连接的次数,可以提高动态、数据库驱动之类网站的运行速度。 Memcached在使用是比较简单的,在操作上基本…...
嵌入式学习笔记——STM32单片机开发前的准备
STM32单片机开发前的准备1.集成开发环境的选取STM32 CubeIDEKEIL_MDK2.KEIL_MDK环境搭建安装包获取及安装芯片包下载及安装工程建立(STM32F407VET6为例)1.新建工程文件夹2.新建工程3.安装ST-LINK以及CH340的驱动4.设置KEIL,并烧录本文重点1.集成开发环境的选取 前面…...
客户案例|FPGA研发管理解决方案:UniPro瀑布+敏捷 打造高效能组织
2023开年以来,新享科技项目管理软件UniPro收获一波客户侧的点赞好评。在过去一年中,UniPro不断与客户保持高频沟通,满足客户需求为出发点,以产品功能实现为落脚点,不断打磨产品。 以UniPro客户京微齐力为例࿰…...
【信息学奥赛】1400:统计单词数
统计单词数也需要分割单词,如果使用字符数组来做的话,其实和1144:单词翻转类似,但是我一直只能通过四个样例,估计边界处理条件还是有点问题。 不过经过打印字符串长度之后发现了之前遇到的一个问题,即fget…...
# 技术详解: 利用CI同步文章以及多端发布
技术详解: 利用CI同步文章以及多端发布 技术详解: 利用CI同步文章以及多端发布 前言文章的同步实现的细节 思路文章元数据的定义和提取修改文章的优化本地图片资源上传CDN并替换本地link 终于到了 CI 的部分了最后来一些碎碎念 前言 前几天我更新了一篇简单技术总结之后&am…...
分形维数的计算方法汇总
以下是常用的时间序列分形维数计算方法及相应的参考文献:Hurst指数法Hurst指数法是最早用于计算分形维数的方法之一,其基本思想是通过计算时间序列的长程相关性来反映其分形特性。具体步骤是:(1) 对原始时间序列进行标准化处理。(2) 将序列分…...
微积分小课堂:积分(从微观趋势了解宏观变化)
文章目录 引言I. 预备知识: 积分效应1.1 闯黄灯1.2 公司利润(飞轮效应)1.3 飞轮效应II 积分2.1 积分的计算2.2 积分思想的本质引言 微分解决的问题是从宏观变化了解微观趋势;积分和微分刚好相反,是从微观去看宏观变化。 通过积分效应,提升我们的认识水平,同时能用一些工…...
4道数学题,求解极狐GitLab CI 流水线|第4题:合并列车
本文来自: 武让 极狐GitLab 高级解决方案架构师 💡 极狐GitLab CI 依靠其一体化、轻量化、声明式、开箱即用的特性,在开发者群体中的使用率越来越高,在国内企业中仅次于 Jenkins ,排在第二位。 极狐GitLab 流水线有 4…...
代码规范简述
目录 命名规范 代码格式 OOP规约 集合规范 并发规范 SQL语句规范 SQL 建表规范 SQL 索引规范 SQL 查询规范 控制语句规范 Javadoc 规范 其他规范 命名规范 1、包名:使用小写字母,多个单词之间用"."分隔,例如ÿ…...
【Java集合框架】篇五:Map接口
1. Map及实现类特点 Map:存储key-value HashMap:线程不安全,效率高,key和value都可以为null,底层使用 数组单向链表红黑树 结构(jdk8)。 LinkedHashMap:是HashMap的子类࿰…...
Typroa安装教程
Markdown 是一种轻量级标记语言,创始人为约翰格鲁伯(John Gruber)。 它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTML)文档。这种语言吸收了很多在电子邮件中已有的纯文本标记…...
【MySQL】存储引擎
目录 1.MySQL体系结构 2.存储引擎介绍 3.存储引擎特点 4.存储引擎选择 1.MySQL体系结构 MySQL整体的逻辑结构可以分为4层,客户层、服务层、存储引擎层、数据层 客户层 客户层:进行相关的连接处理、权限控制、安全处理等操作 服务层 服务层负责与客户层进行连接处理、处…...
芯驰(E3-gateway)开发板环境搭建以及调试遇到问题的解决
1-Windows下环境配置 可以在Windows上使用命令行或者IAR IDE编译SSDK项目。Windows编译依赖的工具已经包含在 prebuilts/windows 目录中,包括编译器、Python和命令行工具。 1.1.1 CMD SSDK集成 msys 工具,可以在Windows命令行中完成SDK的配置、编译和…...
【大数据监控】Prometheus、Node_exporter、Graphite_exporter安装部署详细文档
目录Prometheus简介下载软件包安装部署创建用户创建Systemd服务修改配置文件prometheus.yml启动Prometheusnode exporter下载软件包安装部署添加用户创建systemd服务启动node_exportergraphite_exporter下载软件包安装部署创建systemd服务启动 graphite_exporterPrometheus 简介…...
《C++ Primer》 第十一章 关联容器
《C Primer》 第十一章 关联容器 11.1 使用关联容器 使用map: //统计每个单词在输入中出现的次数 map<string, size_t> word_count;//string到size_t的空map string word; while(cin>>word)word_count[word];//提取word的计数器并将其加1 for(const auto &w:…...
WebRTC标准与框架解读(1)
1、如果让我来设计webrtc框架我在分析源码的时候,都喜欢做这样一件事情:如果让我来设计它,我会怎么做?大家可以紧跟我的思路,分析一下WebRTC为什么如此设计。为了对整个框架有有一个全面的了解,我们首先要做…...
数据结构的一些基础概念
一 基本术语 数据:是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。 数据元素:是组成数据的,有一定意义的基本单位,在计算机中通常作为整体处…...
【Python每日一练】总目录(不断更新中...)
Python 2023.03 20230303 1. 两数之和 ★ 2. 组合总和 ★★ 3. 相同的树 ★★ 20230302 1. 字符串统计 2. 合并两个有序链表 3. 下一个排列 20230301 1. 只出现一次的数字 2. 以特殊格式处理连续增加的数字 3. 最短回文串 Python 2023.02 20230228 1. 螺旋矩阵 …...
latex插入图片(自用)
加入宏包:\usepackage{graphicx} 使用 \includegraphics 命令进行插图。 \includegraphics[]{}: 第一参数[]:对图片做一些适当的调整(设定图片的高度和宽度或者按比例缩放) 第二参数{}:图片的名字…...
【微信小程序】-- 网络数据请求(十九)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...
K8S 实用工具之一 - 如何合并多个 kubeconfig?
开篇 📜 引言: 磨刀不误砍柴工工欲善其事必先利其器 K8S 集群规模,有的公司倾向于少量大规模 K8S 集群,也有的公司会倾向于大量小规模的 K8S 集群。 如果是第二种情况,是否有一个简单的 kubectl 命令来获取一个 kubec…...
阿里云ECS服务器的6大功能组件
阿里的云服务在国内可以说是首屈一指的了,因此他们家的云服务器也是最受欢迎的。那么,你知道阿里云服务器ECS有哪些功能组件吗?不清楚不要紧,下面服务器吧小编带大家来看看。 在了解之前我们来看一张阿里云服务器ECS的产品组件架…...
外贸建站多少钱?不同预算对应的建站方案!
外贸建站多少钱? 答案是:3000左右。 作为一个外贸企业的经营者,我们深知一个优质的外贸网站对于企业的重要性。 然而,建立一个优质的外贸网站需要耗费大量的时间和资金,因此我们需要在预算有限的情况下,…...
Vue3中hook的使用及使用中遇到的坑
目录前言一,什么是hook二, hook函数的使用2.1 铺垫2.2 hook函数的写法2.3 使用写好的hook函数后记前言 在学习Es6的时候,我们开始使用类与对象,开始模块化管理;在Vue中我们可以使用mixin进行模块化管理;Vu…...
五莲网站建设报价/请输入搜索关键词
一、编程语言分类:1、按特性分类:机器语言:编程入门非常困难,执行速度最快。汇编语言:编程相对机器语言简单(采用助记符编程),针对某种具体的CPU。高级语言:贴近生活中的…...
腾龙官方网站做号软件/微信推广费用一般多少
安装完WinDbug之后,在WinDbug路径下会有一个UMDH.exe的文件,通过这个文件可以通过“栈回溯数据库”的方式定位应用程序内存泄露的地方。 The User-Mode Dump Heap (UMDH) tool, Umdh.exe, analyzes the Microsoft Windows heap memory allocations for a…...
看电视剧的免费网站/推广引流最快的方法
跨浏览器 跨域资源共享 解决方案参考文章: (1)跨浏览器 跨域资源共享 解决方案 (2)https://www.cnblogs.com/kasmine/p/6440571.html 备忘一下。...
做时时彩网站微信平台/域名备案查询系统
oracle 设置日期的默认值 1.修改日期字段的默认值为但前系统的时间: alter table 表名 modify 日期字段 DATE default sysdate not null ; 2.修改日期字段的默认值为指定的时间:我们使用 to_date(2003-12-19,yyyy-mm-dd) to_date(2003-12-17 0…...
wordpress的标签有什么用/seo整站优化多少钱
一、前言 时间子系统中的tick device layer主要涉及kernel/time/tick-*相关的文件,本文的主要内容就是从high level层次(不纠缠在具体的每行代码)描述tick device layer的运作逻辑。 如果说每个.c文件是一个模块的话,我们可以首…...
个人备案网站做商业/营销策略都有哪些
最近在工作中遇到一个非常奇怪的问题,在两台主主同步的mysql数据库中,经常出现修改表结构后,两个库中结构不一致的情况,查看同步状态,木有任何报错,数据可正常同步,我自己在操作数据库进行索引创…...