四十六、Qt网络(六)UDP

本文介绍了UDP协议的基本概念及其在Qt中的应用。通过一个简单的C/S模型示例,详细讲解了如何使用QUdpSocket类进行数据报的发送与接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一节讲述UDP编程的知识。UDP(User Datagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接协议。对于UDP我们不再进行过多介绍,如果你对UDP不是很了解,而 且不知道它有什么用,那么我们这里就举个简单的例子:我们现在几乎每个人都使用的腾讯QQ,其聊天时就是使用UDP协议进行消息发送的。就像QQ那样,当 有很多用户,发送的大部分都是短消息,要求能及时响应,并且对安全性要求不是很高的情况下使用UDP协议。

在Qt中提供了QUdpSocket 类来进行UDP数据报(datagrams)的发送和接收。这里我们还要了解一个名词Socket,也就是常说的“套接字”。 Socket简单地说,就是一个IP地址加一个port端口。因为我们要传输数据,就要知道往哪个机子上传送,而IP地址确定了一台主机,但是这台机子上 可能运行着各种各样的网络程序,我们要往哪个程序中发送呢?这时就要使用一个端口来指定UDP程序。所以说,Socket指明了数据报传输的路径。

下面我们将编写两个程序,一个用来发送数据报,可以叫做客户端;另一个用来接收数据报,可以叫做服务器端,它们均应用UDP协议。这样也就构成了所谓的C/S(客户端/服务器)编程模型。我们会在编写程序的过程中讲解一些相关的网络知识。

(一)发送端(客户端)

1. 我们新建 Qt4 Gui Application ,工程名为“ udpSender ”,选中 QtNetwork 模块, Base class 选择 QWidget

2. 我们在 widget.ui 文件中,往界面上添加一个 Push Button ,更改其显示文本为“开始广播”,然后进入其单击事件槽函数。

Hosted by ImageHost.org

3. 我们在 widget.h 文件中更改。

添加头文件:#include <QtNetwork>

添加private私有对象:QUdpSocket *sender;

4. 我们在 widget.cpp 中进行更改。

在构造函数中添加:sender = new QUdpSocket(this);

更改“开始广播”按钮的单击事件槽函数:

void Widget::on_pushButton_clicked() //发送广播

{

QByteArray datagram = “hello world!”;

sender->writeDatagram(datagram.data(),datagram.size(),

QHostAddress::Broadcast,45454);

}

这里我们定义了一个QByteArray类型的数据报datagram,其内容为“hello world!”。然后我们使用QUdpSocket类的writeDatagram()函数来发送数据报,这个函数有四个参数,分别是数据报的内容,数据 报的大小,主机地址和端口号。对于数据报的大小,它根据平台的不同而不同,但是这里建议不要超过512字节。这里我们使用了广播地址 QHostAddress::Broadcast,这样就可以同时给网络中所有的主机发送数据报了。对于端口号,它是可以随意指定的,但是一般1024以 下的端口号通常属于保留端口号,所以我们最好使用大于1024的端口,最大为65535。我们这里使用了45454这个端口号,一定要注意,在下面要讲的 服务器程序中,也要使用相同的端口号。

5. 发送端就这么简单,我们运行程序,效果如下。

Hosted by ImageHost.org

(二)接收端(服务器端)

1. 我们新建 Qt4 Gui Application ,工程名为“ udpReceiver ”,选中 QtNetwork 模块, Base class 选择 QWidget 。此时工程文件列表中应包含两个工程,如下图。

Hosted by ImageHost.org

2. 我们在 udpReceiver 工程中的 widget.ui 文件中,向界面上添加一个 Label 部件,更改其显示文本为“等待接收数据!”,效果如下。

Hosted by ImageHost.org

3. 我们在 udpReceiver 工程中的 widget.h 文件中更改。

添加头文件:#include <QtNetwork>

添加private私有对象:QUdpSocket *receiver;

添加私有槽函数:

private slots:

void processPendingDatagram();

4. 我们在 udpReceiver 工程中的 widget.cpp 文件中更改。

在构造函数中:

receiver = new QUdpSocket(this);

receiver->bind(45454,QUdpSocket::ShareAddress);

connect(receiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));

我们在构造函数中将receiver绑定到45454端口,这个端口就是上面发送端设置的端口,二者必须一样才能保证接收到数据报。我们这里使用了 绑定模式QUdpSocket::ShareAddress,它表明其他服务也可以绑定到这个端口上。因为当receiver发现有数据报到达时就会发出 readyRead()信号,所以我们将其和我们的数据报处理函数相关联。

数据报处理槽函数实现如下:

void Widget::processPendingDatagram() //处理等待的数据报

{

while(receiver->hasPendingDatagrams()) //拥有等待的数据报

{

QByteArray datagram; //拥于存放接收的数据报

datagram.resize(receiver->pendingDatagramSize());

//让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据

receiver->readDatagram(datagram.data(),datagram.size());

//接收数据报,将其存放到datagram中

ui->label->setText(datagram);

//将数据报内容显示出来

}

}

5. 我们在工程列表中 udpReceiver 工程上点击鼠标右键,在弹出的菜单上选择 run 菜单来运行该工程。

Hosted by ImageHost.org

6. 第一次运行该程序时,系统可能会提示警告,我们选择“解除阻止”。

Hosted by ImageHost.org

如果是在linux下,你可能还需要关闭防火墙。

7. 我们同时再运行 udpSender 程序。然后点击其上的“发送广播”按钮,这时会在 udpReceiver 上显示数据报的内容。效果如下。

Hosted by ImageHost.org

可以看到,UDP的应用是很简单的。我们只需要在发送端执行writeDatagram()函数进行数据报的发送,然后在接收端绑定端口,并关联readyRead()信号和数据报处理函数即可。

下一节我们讲述TCP的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值