QT基础(18)- QAbstractSocket

news2024/11/24 16:33:43

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客户端其实是很容易的一般需要一下几步

  1. 包含QTcpSocket头文件:#include <QTcpSocket>
  2. 创建QTcpSocket对象:
QTcpSocket* socket = new QTcpSocket(this);
  1. 连接服务器:
socket->connectToHost("192.168.1.106", 6000);

这里使用connectToHost函数连接服务器。如果连接成功,QTcpSocket会发出connected()信号;如果连接失败,会发出error()信号。

  1. 处理连接结果:
if(socket->waitForConnected()){
    // 连接成功
} else {
    // 连接失败
}

waitForConnected会阻塞进程

  1. 发送数据:
QString dataStr = "Hello";
socket->write(dataStr.toUtf8());
  1. 接收数据:
connect(socket, &QTcpSocket::readyRead, this, [&](){
    QByteArray data = socket->readAll();
    // 处理接收到的数据
});

使用readyRead()信号接收数据,然后使用readAll()函数读取接收到的数据。注意,readyRead()信号可能会被多次触发,所以要使用while循环读取所有数据。

  1. 断开连接:
socket->disconnectFromHost();

使用disconnectFromHost()函数断开与服务器的连接。

2 QAbstractSocket

2.1 简介

以下内容来自官方,本人认为已经讲解的非常清晰明了:

QAbstractSocket是QTcpSocket和QUdpSocket的基类,包含这两个类的所有共同功能。如果需要使用套接字,可以选择以下两种方式:

  1. 实例化QTcpSocket或QUdpSocket。
  2. 创建原生套接字描述符,实例化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::TcpSocketTCP套接字。
QAbstractSocket::UdpSocketUDP套接字。
QAbstractSocket::SctpSocketSCTP套接字(从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::Socks5ProxySocks5代理
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 协议的网络通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文献阅读(47)—— 遗传数据研究近视和眼压与视网膜脱落的关系

文献阅读&#xff08;47&#xff09;—— 遗传数据研究近视和眼压与视网膜脱落的关系 文章目录文献阅读&#xff08;47&#xff09;—— 遗传数据研究近视和眼压与视网膜脱落的关系遗传数据研究近视和眼压与视网膜脱落的关系先验知识/知识拓展文章结构文章结果1. 视网膜脱落风险…

centos8安装docker运行java文件

本文由个人总结&#xff0c;如需转载使用请标明原著及原文地址 这里是基于我前一篇搭的centos8服务器做的&#xff0c;如果yum baseos源或appstream源有问题可以去看看前一篇 https://blog.csdn.net/qq_36911145/article/details/129263830 1.安装docker 1.1配置docker yum…

惠普战66pro如何选购内存条?一篇文章讲解清楚

笔记本&#xff1a;惠普 ZHAN66 PRO CPU&#xff1a;Intel Core™ i-8565U CPU 1.80GHz 内存条&#xff1a;Samsung PS: 如果有需要更换硬盘的可以看我之前发的文章&#xff0c;博主进行了长时间的测试。 硬盘选购长测评 文章目录前言一、内存是什么&#xff1f;二、如何操作呢…

错误:EfficientDet网络出现“No boxes to NMS“并且mAP:0.0的解决方案

近日&#xff0c;在使用谷歌新推出来的一个网络EfficientDet进行目标检测训练自己的数据集的时候&#xff0c;出现了如下错误&#xff1a; 其中项目开源地址是&#xff1a;https://github.com/toandaominh1997/EfficientDet.Pytorch 上面截图中的1和2代表我的类别名称。读者可…

【计算机二级python】综合题题目

计算机二级python真题 文章目录计算机二级python真题一、八十天环游世界二、八十天环游世界 问题一二、八十天环游世界 问题二一、八十天环游世界 附件中保存1个文本文件&#xff0c;分别对应2个问题‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬…

315线上知识竞赛答题活动方案及模板分享

315线上知识竞赛答题活动方案及模板分享在315国际消费者权益日来临之际&#xff0c; 很多单位推出有奖知识竞答&#xff0c; 希望大家在了解专业知识的同时&#xff0c; 还可以拿到自己喜欢的奖品&#xff01;这是消费者委员会和监管局联合举办的“315消费知识在线有奖竞答”活…

Springboot怎么集成Thymeleaf模板引擎?

Thymeleaf介绍Thymeleaf&#xff0c;是一个XML/XHTML/HTML模板引擎&#xff0c;开源的java库&#xff0c;可以用于SpingMVC项目中&#xff0c;用于代替JSP、FreeMarker或者其他的模板引擎&#xff1b;页面与数据分离&#xff0c;提高了开发效率&#xff0c;让代码重用更容易。S…

【JavaScript速成之路】JavaScript流程控制

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言1&#xff0c;流程控制2&#xff0c;分支结构2.1&#xff0c;if语句2.2&…

时机将至,名创优品或将再掀起一波消费热浪

北京时间2月28日&#xff0c;名创优品发布2023财年中报&#xff0c;财报显示&#xff0c;2023财年第二季度营收规模有所收窄&#xff0c;但净利润、毛利率、门店数量均实现了不错的增长&#xff0c;总体表现可圈可点。 &#xff08;资料来源&#xff1a;富途牛牛&#xff09; …

PIC单片机的快速代码生成和调试过程

1.相关工具说明&#xff1a;MCC ...................................Pic的代码模板软原始安装包&#xff1a;mcc-installer-5.2.2-windows.exeMPLAB X IDE ........................... 集成开发环境原始安装包&#xff1a;MPLABX-v6.00-windows-installer.exe编译环境&#x…

自动驾驶目标检测项目实战——基于深度学习框架yolov的交通标志检测

自动驾驶目标检测项目实战——基于深度学习框架yolov的交通标志检测 目前目标检测算法有很多&#xff0c;流行的就有faster-rnn和yolov&#xff0c;本文使用了几年前的yolov3框架进行训练&#xff0c;效果还是很好&#xff0c;当然也可以使用更高版本的Yolov进行实战。本代码使…

八股总结(一)C++语法、内存管理、新标准、STL

layout: post title: 八股总结&#xff08;一&#xff09;C语法、内存管理、新标准、STL description: 八股总结&#xff08;一&#xff09;C语法、内存管理、新标准、STL tag: C 文章目录基础语法语言特性面向对象的三大特性&#xff1f;C中新增了string&#xff0c;它与C语言…

Acwing---843. n-皇后问题

n-皇后问题1.题目2.基本思想3.代码实现1.题目 n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 …

数据库调优策略

1.数据库调优的措施 1.1.调优的目标 尽可能节省系统资源&#xff0c;以便系统可以提供更大负荷的服务。(吞吐量更大)合理的结构设计和参数调整&#xff0c;以提高用户操作 响应的速度。(响应速度更快)减少系统的瓶颈&#xff0c;提高MySQL数据库整体的性能 1.2.如何定位调优…

Qt 绘制图表 - Qt Charts版

一、前言 自从 Qt 发布以来&#xff0c;给广大跨平台界面研发人员带来了无数的福利。但是Qt自己却一直没有提供自带的图表库&#xff0c;这就使得 QWT、QCustomPlot 等第三方图表库有了巨大的生存空间&#xff0c;为了降低开发成本&#xff0c;大家都涌向了这些第三方库。这种…

appium的安装详解

安装appium 爬虫手机APP需要实现自动化&#xff0c;所以要使用appnium来实现点击&#xff0c;输入&#xff0c;滑动等操作。由于appnium的安装较为繁琐&#xff0c;所以特意整理一篇文章来展示安装的详细过程过程中。 安装appnium共有3个步骤 安装 Android SDK安装 JDK安装 …

W800系列|ST-LINK|STM32最小版|HEX文件|CKLINK|DebugServer|学习(3):自制cklink调试工具

硬件准备 1.stm32最小系统板&#xff1a;stm32c8t6 2.stlink下载器&#xff1a;stlink v2版本 软件安装&#xff1a; 1、STM32 ST-LINK Utility&#xff08;官网下载&#xff09; 2、csky IDE: 剑池CDK集成开发环境V2.18.2 https://occ.t-head.cn/community/download?id…

链接投票二维码制作制作投票链接视频选举投票制作

关于微信投票&#xff0c;我们现在用的最多的就是小程序投票&#xff0c;今天的网络投票&#xff0c;在这里会教大家如何用“活动星投票”小程序来进行投票。我们现在要以“信赖挚友”为主题进行一次投票活动&#xff0c;我们可以在在微信小程序搜索&#xff0c;“活动星投票”…

activiti整合springBoot其他操作

如果单纯使用activiti进行流程的自动控制&#xff0c;是可以实现的。但是通常我们都需要结合自定义的表&#xff0c;便于在流程执行中更加清晰的看到每一个流程实例节点的具体信息。关联自定义表与activiti表才能完成真正的业务 BusinessKey关联 // 定义businessKey Test pub…

【UML+OOPC嵌入式C语言开发】使用C语言实现一个面向对象语言才能够实现的类

文章目录简述OOPC开发环境知识讲解函数示例类的实现示例接口实现示例&#xff08;前面两部分有点无聊&#xff0c;如果大家没兴趣看可以直接从知识讲解开始看&#xff09; 简述OOPC oopc&#xff0c;是一种轻量级的面向对象的C语言编程框架&#xff0c; LW_OOPC是Light-Weight …