头文件:#include
qmake: QT+=network
继承于:QAbstractSocket
注:此类中所有的函数都是可重入函数(允许被递归调用的函数。函数的递归调用是指当一个函数正被调用尚未返回时,又直接或间接调用函数本身。)。
(qmake在pro文件中添加,直接将QT+=network添加上即可,如果是VS2015环境,则在创建时勾上Network模块即可。QT VS TOOLS中的Qt Project Settings也可以添加该模块。)
如果工程已经创建好,QT VS TOOLS中又没有相关选项,则在属性->配置属性->Qt Project Settings->Qt Modules中添加"network",不同模块间用“;”分隔。qmake等其他路径会自动包含。
注:有时候包含了添加了模块,也包含了头文件,可是编译报错找不到XXX对象,找不到头文件等。请仔细检查一下程序,看是不是哪里写错了,比如QLabel的第一个L写成了小写等粗心的错误。
UDP是什么:
UDP(用户数据报协议)是一种轻量级、不可靠、面向数据报、无连接的协议。当可靠性不重要时,可以使用它。QUdpSocket
是QAbstractSocket 的子类,允许您发送和接收 UDP 数据报。
UDP怎么使用:
使用此类的最常见方式是使用bind()绑定到地址和端口,然后调用 writeDatagram()和readDatagram() 或receiveDatagram () 来传输数据。如果要使用标准QIODevice (输入/输出设备的基类)函数read ()、readLine()、write() 等,则必须首先通过调用 connectToHost () 将套接字直接连接到对等体
每次将数据报写入网络时,套接字都会发出bytesWritten () 信号。如果您只想发送数据报,则不需要调用 bind ()。
每当数据报到达时,都会发出readyRead() 信号。在这种情况下,hasPendingDatagrams() 返回 。调用pendingDatagramSize() 以获取第一个挂起的数据报的大小,并readDatagram() 或receiveDatagram() 来读取它。
注:当您收到 readyRead () 信号时,应读取传入的数据报,否则不会为下一个数据报发出此信号。
官方示例:
void Server::initSocket()
{
udpSocket = new QUdpSocket(this);//创建一个新的Udp套接字
udpSocket->bind(QHostAddress::LocalHost, 7755);//绑定本机IP,绑定7755端口
connect(udpSocket, &QUdpSocket::readyRead,
this, &Server::readPendingDatagrams);//收到readyRead信号,则调用读取数据报的函数
}
//读取数据报函数
void Server::readPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QNetworkDatagram datagram = udpSocket->receiveDatagram();//读取数据报
processTheDatagram(datagram);
}
}
UDP有点对点的单播,也有一对多的多播还有广播。
使用联接多播组() 和离开多播组 () 控制组成员身份,使用 QAbstractSocket::多播选项和QAbstractSocket::多播循环选项设置 TTL 和环回套接字选项。使用setMulticast 接口() 来控制多播数据报的传出接口,使用多播接口() 来查询它。
使用 QUdpSocket,您还可以使用connectToHost() 建立与 UDP 服务器的虚拟连接,然后使用read() 和write() 交换数据报,而无需为每个数据报指定接收方。
QUdpSocket::QUdpSocket(QObject *parent = nullptr) 创建 QUdpSocket
对象。 父级传递给QObject 构造函数。
[virtual]QUdpSocket::~QUdpSocket() 析构函数,用来销毁套接字
bool QUdpSocket::hasPendingDatagrams() const 如果至少有一个数据报等待读取,则返回;否则返回
truefalse
bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)
用于加入多播组,如果成功,则返回此函数。否则,它返回并相应地设置套接字错误。
bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress,
const QNetworkInterface &iface) 加入MulticastGroup,这是一个重载函数
bool QUdpSocket::leaveMulticastGroup(const QHostAddress
&groupAddress) 离开多播组,此函数的调用应与:joinMulticastGroup()的参数相同
bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
QNetworkInterface QUdpSocket::multicastInterface() const
多播接口,返回多播数据报的传出接口。这对应于 IPv4 套IP_MULTICAST_IF的插槽选项和 IPv6
套IPV6_MULTICAST_IF的插槽选项。如果以前没有设置接口,则此函数将返回无效的QNetworkInterface。套接字必须位于绑定状态中,否则将返回无效的QNetworkInterface。
qint64 QUdpSocket::pendingDatagramSize() const 返回第一个挂起的 UDP数据报的大小。如果没有可用的数据图,则此函数返回 -1。
qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize,
QHostAddress *address = nullptr, quint16 port = nullptr)
接收的数据报不超过最大大小字节,并存储在数据中。发件人的主机地址和端口存储在地址和端口中(除非指针为 )。nullptr
返回成功时的数据报的大小;否则返回 -1。
如果maxSize太小,则数据报的其余部分将丢失。为避免数据丢失,请调用挂起的数据量大小 ()
以确定挂起的数据报的大小,然后再尝试读取它。如果maxSize为 0,则数据报将被丢弃。
QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize = -1)
接收数据不超过maxSize字节的数据报 如果maxSize太小,则数据报的其余部分将丢失。如果maxSize为
0,则数据报将被丢弃。如果maxSize为 -1(默认值),则此函数将尝试读取整个数据报。
void QUdpSocket::setMulticastInterface(const QNetworkInterface
&iface) 设置多播接口
qint64 QUdpSocket::writeDatagram(const char *data, qint64 size,
const QHostAddress &address, quint16 port)
将数据发送到端口的主机地址。返回成功时发送的字节数;否则返回
-1。以大小大小将数据发送到端口的主机地址。返回成功时发送的字节数;否则返回 -1。
数据报始终作为一个块写入。数据报的最大大小高度依赖于平台,但可以低至 8192 字节。如果数据图太大,则此函数将返回-1,错误()
将返回DatagramTooLargeRror。
发送大于 512 字节的数据报通常不建议,因为即使成功发送数据报,在到达最终目的地之前,它们也可能被 IP 层分段。
警告:在连接的 UDP 套接字上调用此函数可能会导致错误且未发送数据包。如果使用连接的套接字,请使用write() 发送数据报。
qint64 QUdpSocket::writeDatagram(const QNetworkDatagram &datagram)
重载函数
使用网络接口和跃点计数限制将数据报发送到数据报中包含的主机地址和端口号。如果未设置目标地址和端口号,则此函数将发送到传递到ConnectToHost()
的地址。 警告:在连接的 UDP 套接字上调用此函数可能会导致错误且未发送数据包。如果使用连接的套接字,请使用write()
发送数据报。
qint64 QUdpSocket::writeDatagram(const QByteArray &datagram, const
QHostAddress &host, quint16 port) 这是一个重载函数。
将数据报数据报发送到主机地址主机和端口端口。
函数返回如果成功时发送的字节数,如果遇到错误,则返回 -1。
服务器加入到组播:
udp = new QUdpSocket(this);
udp->bind(QHostAddress::Any,9999,QUdpSocket::ShareAddress);
udp->joinMulticastGroup(QHostAddress("192.168.0.1"));
收到消息处理的函数:
connect(udp,SIGNAL(readyRead()),this,SLOT(rec_msg)));
void rec_msg()
{
while (udp->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udp->pendingDatagramSize());
revWBudp->readDatagram(datagram.data(),datagram.size());
qDebug()<<"data ;"<<datagram.toHex();
// 进行处理的一些操作
}
}
断开
udp->disconnected();
delete udp;
udp = nullptr;
QHostAddress类提供一个IP地址。
这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址。
QHostAddress通常与QTcpSocket、QTcpServer、QUdpSocket一起使用,来连接到主机或建立一个服务器。
可以通过setAddress()来设置一个主机地址,使用toIPv4Address()、toIPv6Address()或toString()来检索主机地址。你可以通过protocol()来检查协议类型。
枚举 QHostAddress::SpecialAddress:
常量 值 描述
QHostAddress::Null 0 空地址对象,相当于QHostAddress()。
QHostAddress::LocalHost 2 IPv4本地主机地址,相当于QHostAddress(“127.0.0.1”)。
QHostAddress::LocalHostIPv6 3 IPv6本地主机地址,相当于 QHostAddress(“::1”)。
QHostAddress::Broadcast 1 Pv4广播地址,相当于QHostAddress(“255.255.255.255”)。
QHostAddress::AnyIPv4 6 IPv4 any-address,相当于QHostAddress(“0.0.0.0”)。与该地址绑定的socket将只监听IPv4接口。
QHostAddress::AnyIPv6 5 IPv6 any-address,相当于QHostAddress(“::”)。与该地址绑定的socket将只监听IPv4接口。
QHostAddress::Any 4 双any-address栈,与该地址绑定的socket将侦听IPv4和IPv6接口。
构造一个QHostAddress,通过toString()来获取对应的IP地址:
QHostAddress address = QHostAddress(QHostAddress::LocalHost);
QString strIPAddress = address.toString();
过滤
本地链路地址范围:192.254.1.0 - 192.254.254.255
bool isLinkLocalAddress(QHostAddress addr){
quint32 nIPv4 = addr.toIPv4Address();
quint32 nMinRange = QHostAddress(“192.168.0.1”).toIPv4Address();
quint32 nMaxRange = QHostAddress(“192.254.254.255”).toIPv4Address();
if ((nIPv4 >= nMinRange) && (nIPv4 <= nMaxRange)) {
return true;
} else {
return false;
} }