首页 » PHP教程 » phpsoketread清算技巧_Qt UDP收集编程

phpsoketread清算技巧_Qt UDP收集编程

duote123 2024-11-10 0

扫一扫用手机浏览

文章目录 [+]

UDP是一个轻量级、不可靠、面向数据报的、无连接的协议,多用于可靠性哀求不严格,不是非常主要的传输。

QUdpSocket类继续自QAbstractSocket,用来发送和吸收UDP数据报,”Socket”即套接字,套接字即IP地址+端口号。
个中IP地址指定了网络中的一台主机,二端口号则指定了该主机上的一个网络程序,利用套接字即可实现网络上的两个运用程序之间的通信。

phpsoketread清算技巧_Qt  UDP收集编程

QUdpSocket支持IPv4广播,要广播数据报,则只需发送到一个分外的地址QHostAddress::Broadcast(即255.255.255.255),数据报一样平常建议发送字节数小于512字节。
端口号选择1024-65535(1024以下的常用作保留端口号,如FTP常用端口号21,Telnet常用端口号23,DNS域名做事器常用端口53等)。

phpsoketread清算技巧_Qt  UDP收集编程
(图片来自网络侵删)
1.1 旗子暗记

1.2 公有函数

函数

描述

bool hasPendingDatagrams() const

如果至少有一个数据报等待读取,则返回true;否则返回false。

bool joinMulticastGroup(const QHostAddress &groupAddress)

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

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

这是一个重载函数。
在接口上加入组播组地址groupAddress。

bool leaveMulticastGroup(const QHostAddress &groupAddress)

在操作系统选择的默认接口上离开groupAddress指定的组播组。
套接字必须处于BoundState状态,否则会发生缺点。

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

这是一个重载函数。
离开接口上指定groupAddress的组播组。

QNetworkInterface multicastInterface() const

返回多播数据报的出接口。
这对应于IPv4套接字的IP_MULTICAST_IF套接字选项和IPv6套接字的IPV6_MULTICAST_IF套接字选项。
如果之前没有设置接口,这个函数将返回一个无效的qnetworkinterface。
套接字必须处于BoundState状态,否则返回无效的QNetworkInterface。

qint64 pendingDatagramSize() const

返回第一个挂起的UDP数据报的大小。
如果没有可用的数据报,这个函数返回-1。

qint64 readDatagram(char data, qint64 maxSize, QHostAddress address = nullptr, quint16 port = nullptr)

吸收不大于maxSize字节的数据报,并将其存储在数据中。
发送方的主机地址和端口存储在address和port中(除非指针是0)。
成功返回数据报的大小;否则返回1。

QNetworkDatagram receiveDatagram(qint64 maxSize = -1)

吸收一个不大于maxSize字节的数据报,并在QNetworkDatagram工具中返回它,以及发送者的主机地址和端口。
如果可能,该函数还将考试测验确定数据报的目的地址、端口和吸收时的跳数。

void setMulticastInterface(const QNetworkInterface &iface)

将组播数据报的出接口设置为当前接口。
这对应于IPv4套接字的IP_MULTICAST_IF套接字选项和IPv6套接字的IPV6_MULTICAST_IF套接字选项。
套接字必须处于BoundState状态,否则此函数不实行任何操作。

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

将大小为size的数据报发送到端口上的主机地址。
返回成功发送的字节数;否则返回1。

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

这是一个重载函数。
将数据报发送到主机地址和端口。

•从QAbstractSocket继续了37个公共函数,上面有写QAbstractSocket的公有函数

Qt资料领取→「链接」

1.3 发送与吸收函数

QUdpSocket对付发送数据报文供应了三个重载函数:

qint64 writeDatagram(const char data, qint64 size, const QHostAddress &address, quint16 port)//将大小为size的数据报发送到端口上的主机地址。
返回成功发送的字节数;否则返回1。
qint64 writeDatagram(const QNetworkDatagram &datagram)qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)

吸收须要利用Qudpsocket供应的以下函数:

qint64 pendingDatagramSize() constqint64 readDatagram(char data, qint64 maxSize, QHostAddress address = Q_NULLPTR, quint16 port = Q_NULLPTR)//吸收不大于maxSize字节的数据报,并将其存储在数据中。
发送方的主机地址和端口存储在address和port中(除非指针是0)。
成功返回数据报的大小;否则返回1。
QNetworkDatagram receiveDatagram(qint64 maxSize = -1)
1.4 UDP通信流程

2. UDP传送的三种模式

单播模式(unicast):一个UDP客户端发送数据报到指定地址和端口的另一UDP客户端,是一对一的数据传输。

组播模式(multicast):UDP客户端加入到另一个组播IP地址的多播组,成员向组播地址发送的数据报,其加入组播的所有成员都可以吸收到,类似于QQ群功能。
QUdpSocket::joinMulticastGroup()函数实现加入多播组的功能。

广播模式(broadcast):一个UDP客户端发出的数据报,在同一网络范围内其他所有的UDP客户端都可以收到。
QUdpSocket支持IPv4广播。
须要在数据报中指定吸收端地址为QHostAddress::Broadcast,一样平常的广播地址是255.255.255.255。

在单播、广播和多播模式下,UDP程序都是对等的,不像TCP通信分为客户端和做事端。
TCP通信只有单播模式。
UDP通信虽然不能担保数据传输的准确性,但是具有灵巧性,一样平常的即时通信软件都是基于UDP通信的。

QUdpSocket也支持UDP组播。
利用joinMulticastGroup()和leaveMulticastGroup()掌握组成员,利用QAbstractSocket::MulticastTtlOption和QAbstractSocket::MulticastLoopbackOption设置TTL和loopback套接字选项。
利用setMulticastInterface()掌握组播数据报的出接口,利用multicastInterface()查询出接口。

利用QUdpSocket,您还可以利用connectToHost()建立到UDP做事器的虚拟连接,然后利用read()和write()交流数据报,而不须要为每个数据报指定吸收者。

Broadcast Sender、Broadcast Receiver、Multicast Sender和Multicast Receiver示例演示了如何在运用程序中利用QUdpSocket。

2.1 单播

单播(Unicast)是在一个单个的发送者和一个接管者之间通过网络进行的通信。

发送端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class UnicastSender:public QWidget{ Q_OBJECTpublic: UnicastSender(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有正在发送的数据报"); sendBtn = new QPushButton("发送数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); vlayout->addWidget(sendBtn); initSocket(); connect(sendBtn,&QPushButton::released,this,&UnicastSender::sendDatagram); } void initSocket() { udpSoket = new QUdpSocket(this); //不须要连接到做事器 } void sendDatagram() { QByteArray datagram = "数据报:"+QByteArray::number(messageNo); //发送数据,须要指定ip地址和端口号 udpSoket->writeDatagram(datagram,QHostAddress::LocalHost /QHostAddress("81.70.201.21")/,8888); messageNo++; }private: QLabel statusLab; QPushButton sendBtn; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); UnicastSender sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"接管端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class UnicastRecevier:public QWidget{ Q_OBJECTpublic: UnicastRecevier(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有接管到数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); initSocket(); } void initSocket() { udpSoket = new QUdpSocket(this); //吸收者须要绑定ip地址和端口号 udpSoket->bind(QHostAddress::LocalHost/QHostAddress("81.70.201.21")/,8888); connect(udpSoket,&QUdpSocket::readyRead,this,&UnicastRecevier::onReadyread); } void onReadyread() { QByteArray datagram; QHostAddress host; quint16 port; //读取数据 while(udpSoket->hasPendingDatagrams()) { //获取一下下一个数据报的大小 datagram.resize(udpSoket->pendingDatagramSize()); //接管 udpSoket->readDatagram(datagram.data(),datagram.size(),&host,&port); //显示 statusLab->setText(host.toString() +":"+ QString::number(port) +datagram); } }private: QLabel statusLab; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); UnicastRecevier sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"2.2 多播

多播(Multicast)是一点对多点的通信,IPv6没有采取IPv4中的组播术语,而是将广播算作是多播的一个分外例子。

多播与单播步骤是一样的,只有IP地址有所差异。

多播的地址是特定的,D类地址用于多播。
D类IP地址便是多播IP地址,即224.0.0.0至239.255.255.255之间的IP地址,并被划分为局部连接多播地址、预留多播地址和管理权限多播地址3类:

1,局部多播地址:在224.0.0.0~224.0.0.255之间,这是为路由协议和其他用场保留的地址,路由器并不转发属于此范围的IP包2,预留多播地址:在224.0.1.0~238.255.255.255之间,可用于环球范围(如Internet)或网络协议。
3,管理权限多播地址:在239.0.0.0~239.255.255.255之间,可供组织内部利用,类似于私有IP地址,不能用于Internet,可限定多播范围。

多播的程序设计利用setsockopt()函数和getsockopt()函数来实现,组播的选项是IP层的,其选项值和含义拜会11.5所示。

选项

描述

IP_MULTICAST_TTL

设置多播组数据的TTL值

IP_ADD_MEMBERSHIP

在指定接口上加入组播组

IP_DROP_MEMBERSHIP

退出组播组

IP_MULTICAST_IF

获取默认接口或设置接口

IP_MULTICAST_LOOP

禁止组播数据回送

多播程序设计的框架

要进行多播的编程,须要屈服一定的编程框架。
多播程序框架紧张包含套接字初始化、设置多播超时时间、加入多播组、发送数据、吸收数据以及从多播组中离开几个方面。
其步骤如下:

(1)建立一个socket。

(2)然后设置多播的参数,例如超时时间TTL、本地回环容许LOOP等。

(3)加入多播组。

(4)发送和吸收数据。

(5)从多播组离开。

发送端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class MulticastSender:public QWidget{ Q_OBJECTpublic: MulticastSender(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有正在发送的数据报"); sendBtn = new QPushButton("发送数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); vlayout->addWidget(sendBtn); initSocket(); connect(sendBtn,&QPushButton::released,this,&MulticastSender::sendDatagram); } void initSocket() { udpSoket = new QUdpSocket(this); //不须要连接到做事器 } void sendDatagram() { QByteArray datagram = "数据报:"+QByteArray::number(messageNo); //发送数据,须要指定ip地址和端口号,组播ip地址范围:224.0.0.0 - 239.255.255.255 udpSoket->writeDatagram(datagram,QHostAddress("239.255.255.255"),8887); messageNo++; }private: QLabel statusLab; QPushButton sendBtn; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); MulticastSender sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"接管端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class MulticastRecevier:public QWidget{ Q_OBJECTpublic: MulticastRecevier(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有接管到数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); initSocket(); } void initSocket() { udpSoket = new QUdpSocket(this); //吸收者须要绑定ip地址和端口号,许可端口和ip重用,多个socket绑定同一ip和端口 udpSoket->bind(QHostAddress::AnyIPv4,8887,QUdpSocket::BindFlag::ShareAddress | QUdpSocket::BindFlag::ReuseAddressHint); //多播是分组的,加入一个指定组 udpSoket->joinMulticastGroup(QHostAddress("239.255.255.255")); connect(udpSoket,&QUdpSocket::readyRead,this,&MulticastRecevier::onReadyread); } void onReadyread() { QByteArray datagram; QHostAddress host; quint16 port; //读取数据 while(udpSoket->hasPendingDatagrams())//hasPendingDatagrams()如果至少有一个数据报等待读取,则返回true; { //获取一下下一个数据报的大小 datagram.resize(udpSoket->pendingDatagramSize());//pendingDatagramSize()返回第一个挂起的UDP数据报的大小。
//接管 udpSoket->readDatagram(datagram.data(),datagram.size(),&host,&port); //显示 statusLab->setText(host.toString() +":"+ QString::number(port) +datagram); } }private: QLabel statusLab; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); MulticastRecevier sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"

测试效果:

2.3 广播

广播(broadcast)是一点到所有点的通信办法。

广播与组播是一样的,只是ip地址有所不同,而且不用加入指定的组。
单播的数据只是收发数据的特定主机进行处理,组播在特定组之间进行处理,而广播的数据全体局域网都进行处理。

“广播”可以理解为一个人通过广播喇叭对在场的全体说话,这样做的好处是通话效率高,信息一下子就可以通报到全体。

“广播”在网络中的运用较多,如客户机通过DHCP自动得到IP地址的过程便是通过广播来实现的。
但是同单播和多播比较,广播险些占用了子网内网络的所有带宽。
拿开会打一个比方吧,在会场上只能有一个人发言,想象一下如果所有的人同时都用麦克风发言,那会场上就会乱成一锅粥。

在IP网络中,广播地址用IP地址“255.255.255.255”来表示,这个IP地址代表同一子网内所有的IP地址。

发送端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class BroadcastSender:public QWidget{ Q_OBJECTpublic: BroadcastSender(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有正在发送的数据报"); sendBtn = new QPushButton("发送数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); vlayout->addWidget(sendBtn); initSocket(); connect(sendBtn,&QPushButton::released,this,&BroadcastSender::sendDatagram); } void initSocket() { udpSoket = new QUdpSocket(this); //不须要连接到做事器 } void sendDatagram() { QByteArray datagram = "数据报:"+QByteArray::number(messageNo); //发送数据,须要指定ip地址和端口号 udpSoket->writeDatagram(datagram,QHostAddress::Broadcast,8886); messageNo++; }private: QLabel statusLab; QPushButton sendBtn; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); BroadcastSender sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"接管端:

#include <QApplication>#include <QWidget>#include <QLabel>#include <QPushButton>#include <QVBoxLayout>#include <QUdpSocket>class BroadcastRecevier:public QWidget{ Q_OBJECTpublic: BroadcastRecevier(QWidgetparent = nullptr) { resize(300,100); statusLab = new QLabel("没有接管到数据"); auto vlayout = new QVBoxLayout(this); vlayout->addWidget(statusLab); initSocket(); } void initSocket() { udpSoket = new QUdpSocket(this); //吸收者须要绑定ip地址和端口号 udpSoket->bind(QHostAddress::Any,8886,QUdpSocket::BindFlag::ShareAddress | QUdpSocket::BindFlag::ReuseAddressHint); connect(udpSoket,&QUdpSocket::readyRead,this,&BroadcastRecevier::onReadyread); } void onReadyread() { QByteArray datagram; QHostAddress host; quint16 port; //读取数据 while(udpSoket->hasPendingDatagrams())//hasPendingDatagrams()如果至少有一个数据报等待读取,则返回true; { //获取一下下一个数据报的大小 datagram.resize(udpSoket->pendingDatagramSize());//pendingDatagramSize()返回第一个挂起的UDP数据报的大小。
//接管 udpSoket->readDatagram(datagram.data(),datagram.size(),&host,&port); //显示 statusLab->setText(host.toString() +":"+ QString::number(port) +datagram); } }private: QLabel statusLab; int messageNo = 0; QUdpSocket udpSoket;};int main(int argc, char argv[]){ QApplication a(argc, argv); BroadcastRecevier sender; sender.show(); return a.exec();}//包含moc文件#include"main.moc"

测试效果:

文章转自博客园(BORUTO):https://www.cnblogs.com/zhuchunlin/p/16485948.html

Qt资料领取→「链接」

标签:

相关文章

执业药师试卷代码解码药师职业发展之路

执业药师在药品质量管理、用药安全等方面发挥着越来越重要的作用。而执业药师考试,作为进入药师行业的重要门槛,其试卷代码更是成为了药师...

PHP教程 2025-02-18 阅读1 评论0

心灵代码主题曲唤醒灵魂深处的共鸣

音乐,作为一种独特的艺术形式,自古以来就承载着人类情感的表达与传递。心灵代码主题曲,以其独特的旋律和歌词,唤醒了无数人的灵魂深处,...

PHP教程 2025-02-18 阅读1 评论0

探寻福建各市车牌代码背后的文化内涵

福建省,地处我国东南沿海,拥有悠久的历史和丰富的文化底蕴。在这片充满魅力的土地上,诞生了许多具有代表性的城市,每个城市都有自己独特...

PHP教程 2025-02-18 阅读1 评论0

探寻河北唐山历史与现代交融的城市之光

河北省唐山市,一座地处渤海之滨,拥有悠久历史和独特文化的城市。这里既是古丝绸之路的起点,也是中国近代工业的发源地。如今,唐山正以崭...

PHP教程 2025-02-18 阅读1 评论0