Roson的Qt之旅 #117 QTcpSocket和QUdpSocket详细介绍

235 篇文章 179 订阅

CSDN话题挑战赛第2期
参赛话题:Qt应用程序开发

1.QTcpSocket

QTcpSocket类提供了一个TCP socket。

TCP(传输控制协议)是一个可靠的、面向流的、面向连接的传输协议。它特别适用于数据的连续传输。

QTcpSocket是QAbstractSocket的一个便利子类,它允许你建立一个TCP连接并传输数据流。详情请参见:

Roson的Qt之旅#92 QAbstractSocket(Qt套接字基类)_Allen Roson的博客-CSDN博客_qt本地套接字QAbstractSocket使用说明;Qt套接字;Qt Sockethttps://blog.csdn.net/jolin678/article/details/124910073?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166324466916782412537753%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166324466916782412537753&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-124910073-null-null.nonecase&utm_term=QAbstractSocket&spm=1018.2226.3001.4450


注意:TCP套接字不能以QIODevice::Unbuffered模式打开。
另见QTcpServer, QUdpSocket, QNetworkAccessManager


2.QUdpSocket

2.1概述

QUdpSocket类提供了一个UDP套接字。

UDP(用户数据报协议)是一个轻量级的、不可靠的、面向数据报的、无连接的协议。它可以在可靠性不重要时使用。QUdpSocket是QAbstractSocket的一个子类,允许你发送和接收UDP数据报。

使用这个类的最常见方法是使用bind()绑定到一个地址和端口,然后调用writeDatagram()和readDatagram()/receiveDatagram()来传输数据。如果你想使用标准的QIODevice函数read()、readLine()、write()等,你必须首先通过调用connectToHost()将套接字直接连接到一个对等体。
每次有数据报被写入网络时,套接字都会发出bytesWritten()信号。如果你只是想发送数据报,你不需要调用bind()。

只要有数据报到达,就会发出readyRead()信号。在这种情况下,hasPendingDatagrams()返回true。调用pendingDatagramSize()来获得第一个待发数据报的大小,然后调用readDatagram()或receiveDatagram()来读取它。

注意:当你收到readyRead()信号时,应该读取一个传入的数据报,否则这个信号将不会为下一个数据报发射出来。

例子:

  void Server::initSocket()
  {
      udpSocket = new QUdpSocket(this);
      udpSocket->bind(QHostAddress::LocalHost, 7755);

      connect(udpSocket, SIGNAL(readyRead()),
              this, SLOT(readPendingDatagrams()));
  }

  void Server::readPendingDatagrams()
  {
      while (udpSocket->hasPendingDatagrams()) {
          QNetworkDatagram datagram = udpSocket->receiveDatagram();
          processTheDatagram(datagram);
      }
  }

QUdpSocket还支持UDP组播。使用joinMulticastGroup()和leaveMulticastGroup()来控制组成员资格,使用QAbstractSocket::MulticastTtlOption和QAbstractSocket::MulticastLoopbackOption来设置TTL和回环套接字选项。使用setMulticastInterface()来控制组播数据报的出站接口,并使用multicastInterface()来查询它。

使用QUdpSocket,你也可以使用connectToHost()建立一个与UDP服务器的虚拟连接,然后使用read()和write()来交换数据报,而不需要为每个数据报指定接收器。

广播发送器、广播接收器、多播发送器和多播接收器的例子说明了如何在应用程序中使用QUdpSocket。

另请参见QTcpSocket和QNetworkDatagram。


2.2成员函数说明

QUdpSocket::QUdpSocket(QObject *parent = Q_NULLPTR)

创建一个QUdpSocket对象。
parent被传递给QObject构造函数。
也请参见socketType()。

[virtual] QUdpSocket::~QUdpSocket()

销毁套接字,必要时关闭连接。
参见close()。

bool QUdpSocket::hasPendingDatagrams() const

如果至少有一个数据报在等待被读取,则返回true,否则返回false。
参见 pendingDatagramSize() 和 readDatagram()。

bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)

在操作系统选择的默认接口上加入由groupAddress指定的多播组。该套接字必须处于BoundState状态,否则会发生错误。

请注意,如果你试图加入一个IPv4组,你的套接字必须不使用IPv6(或者在双模式下,使用QHostAddress::Any)来绑定。你必须使用QHostAddress::AnyIPv4来代替。

如果成功,该函数返回true;否则返回false并相应地设置套接字错误。

这个函数在Qt 4.8中引入。

参见leaveMulticastGroup()。

bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)

这是一个重载函数。
加入接口iface上的多播组地址groupAddress。
这个函数在Qt 4.8中引入。
也请参见 leaveMulticastGroup()。

bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)

在操作系统选择的默认接口上离开由groupAddress指定的多播组。该套接字必须处于BoundState状态,否则会发生错误。
如果成功,该函数返回true;否则返回false并相应地设置套接字错误。
这个函数在Qt 4.8中引入。
参见joinMulticastGroup()。

bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)

这是一个重载函数。
离开接口iface上由groupAddress指定的多播组。
这个函数在Qt 4.8中引入。
参见joinMulticastGroup()。

QNetworkInterface QUdpSocket::multicastInterface() const

返回多播数据报的出站接口。这对应于IPv4套接字的IP_MULTICAST_IF套接字选项和IPv6套接字的IPV6_MULTICAST_IF套接字选项。如果之前没有设置接口,这个函数会返回一个无效的QNetworkInterface。该套接字必须处于BoundState状态,否则将返回一个无效的QNetworkInterface。
这个函数在Qt 4.8中引入。
参见setMulticastInterface()。

qint64 QUdpSocket::pendingDatagramSize() const

返回第一个待处理的UDP数据报的大小。如果没有可用的数据报,该函数返回-1。
参见hasPendingDatagrams()和readDatagram()。

qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)

接收一个不大于maxSize字节的数据报并将其存储在data中。发送者的主机地址和端口存储在*address和*port中(除非指针为0)。
成功时返回数据报的大小;否则返回-1。
如果maxSize太小,数据报的其余部分将被丢失。为了避免数据丢失,在试图读取数据报之前,应调用pendingDatagramSize()来确定未决数据报的大小。如果maxSize为0,数据报将被丢弃。
参见writeDatagram(), hasPendingDatagrams(), and pendingDatagramSize()。

QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize = -1)

接收一个不超过maxSize字节的数据报,并在QNetworkDatagram对象中返回,同时返回发件人的主机地址和端口。如果可能的话,这个函数还将尝试确定数据报的目的地址、端口和接收时的跳数。
失败时,返回一个报告无效的QNetworkDatagram。
如果maxSize太小,数据报的其余部分将被丢失。如果maxSize为0,数据报将被丢弃。如果maxSize为-1(默认),该函数将尝试读取整个数据报。
参见writeDatagram(), hasPendingDatagrams(), and pendingDatagramSize()。

void QUdpSocket::setMulticastInterface(const QNetworkInterface &iface)

将多播数据包的出站接口设置为接口iface。这对应于IPv4套接字的IP_MULTICAST_IF套接字选项和IPv6套接字的IPV6_MULTICAST_IF套接字选项。该套接字必须处于BoundState状态,否则该函数不做任何事情。
这个函数在Qt 4.8中引入。
参见multicastInterface(), joinMulticastGroup(), and leaveMulticastGroup()。

qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)

将数据报以大小的方式发送到端口端口的主机地址。成功时返回发送的字节数,否则返回-1。
数据报总是被写成一个块。数据报的最大尺寸与平台高度相关,但可以低至8192字节。如果数据报太大,这个函数将返回-1,error()将返回DatagramTooLargeError。

一般来说,发送大于512字节的数据报是不利的,因为即使它们被成功发送,在到达最终目的地之前,它们很可能被IP层分割开来。

警告。在一个连接的UDP套接字上调用这个函数可能会导致错误,并且没有数据包被发送。如果你使用一个连接的套接字,请使用write()来发送数据包。
参见readDatagram()和write()。

qint64 QUdpSocket::writeDatagram(const QNetworkDatagram &datagram)

这是一个重载函数。
将数据报数据报发送到数据报中包含的主机地址和端口号,使用网络接口和跳数限制,也是在这里设置的。如果目标地址和端口号没有设置,该函数将发送至connectToHost()传递的地址。
如果目标地址是IPv6,有一个非空的范围ID,但与数据报中的接口索引不同,则未定义操作系统将选择在哪个接口上发送。

如果成功,该函数返回发送的字节数,如果遇到错误则返回-1。

警告:在一个连接的UDP套接字上调用这个函数可能会导致错误和没有数据包被发送。如果你使用一个连接的套接字,请使用write()来发送数据包。

参见QNetworkDatagram::setDestination(), QNetworkDatagram::setHopLimit(), 和QNetworkDatagram::setInterfaceIndex()。

qint64 QUdpSocket::writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)

这是一个重载函数。
向主机地址host和端口port发送数据报datagram。
如果成功,该函数返回发送的字节数,如果遇到错误则返回-1。


 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen Roson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值