QT学习(网络)
UDP
UDP(UserDatagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接协议。对于UDP我们不再进行过多介绍,如果你对UDP不是很了解,而且不知道它有什么用,那么这里就举个简单的例子:我们现在几乎每个人都使用的腾讯QQ,其聊天时就是使用UDP协议进行消息发送的。就像QQ那样,当有很多用户,发送的大部分都是短消息,要求能及时响应,并且对安全性要求不是很高的情况下使用UDP协议。
在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。 Socket简单地说,就是一个IP地址加一个port端口。因为我们要传输数据,就要知道往哪个机子上传送,而IP地址确定了一台主机,但是这台机子上可能运行着各种各样的网络程序,我们要往哪个程序中发送呢?这时就要使用一个端口来指定UDP程序。所以说,Socket指明了数据报传输的路径。
进入代码环节
***.pro
QT += core gui network
界面如下:
***1.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QUdpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
QUdpSocket *sender;
};
#endif // WIDGET_H
***1.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
sender = new QUdpSocket(this);
}
Widget::~Widget()
{
delete ui;
}
/********************************************************************************************************
这里定义了一个QByteArray类型的数据报datagram,其内容为“hello world!”。
然后使用QUdpSocket类的writeDatagram()函数来发送数据报,这个函数有四个参数,
分别是数据报的内容,数据报的大小,主机地址和端口号。对于数据报的大小,它根据平台的不同而不同,
但是这里建议不要超过512字节。这里使用了广播地址QHostAddress::Broadcast,这样就可以同时给网络中所有的主机发送数据报了。
对于端口号,它是可以随意指定的,但是一般1024以下的端口号通常属于保留端口号,所以我们最好使用大于1024的端口,最大为65535。
我们这里使用了45454这个端口号,一定要注意,在下面要讲的服务器程序中,也要使用相同的端口号。
*********************************************************************************************************/
void Widget::on_pushButton_clicked()// 开始广播
{
QByteArray datagram = "hello world!";
sender->writeDatagram(datagram.data(),datagram.size(), QHostAddress::Broadcast,45454);
}
***2.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QUdpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void processPendingDatagram();
private:
Ui::Widget *ui;
QUdpSocket *receiver;
};
#endif // WIDGET_H
***2.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
receiver = new QUdpSocket(this);
receiver->bind(45454,QUdpSocket::ShareAddress);//将receiver绑定到45454端口,这个端口就是上面发送端设置的端口,二者必须一样才能保证接收到数据报。
connect(receiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));
}
Widget::~Widget()
{
delete ui;
}
/******************************************************************************************************
主要用于接收来自udpSender的数据报,所以需要和udpSender同时使用。
注意事项:第一次运行该程序时,系统可能会提示警告,我们选择“解除阻止”。 注意,如果是在linux下,你可能还需要关闭防火墙。
********************************************************************************************************/
void Widget::processPendingDatagram() //处理等待的数据报
{
while(receiver->hasPendingDatagrams()) //拥有等待的数据报
{
QByteArray datagram; //拥于存放接收的数据报
datagram.resize(receiver->pendingDatagramSize());//让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据
receiver->readDatagram(datagram.data(),datagram.size());//接收数据报,将其存放到datagram中
ui->label->setText(datagram);//将数据报内容显示出来
}
}
学习链接:
网络Utp