QT中的UDP通信

前言:
  前一章我们我们介绍了tcp通信,通过对tcp通信流程熟悉,再来看udp就显得简单多了。使用Qt提供的QUdpSocket进行UDP通信。在UDP方式下,客户端并不与服务器建立连接,它只负责调用发送函数向服务器发送数据。类似的服务器也不从客户端接收连接,只负责调用接收函数,等待来自客户端的数据的到达。
在UDP通信中,服务器端和客户端的概念已经显得有些淡化,两部分做的工作都
大致相同:
   创建套接字
   绑定套接字
    在UDP中如果需要接收数据则需要对套接字进行绑定,只发送数据则不需要对套接字进行绑定。通过调用bind()函数将套接字绑定到指定端口上。
接收或者发送数据
  接收数据
    使用readDatagram()接收数据,函数声明如下:
qint64 readDatagram(char * data, qint64 maxSize,
          QHostAddress * address = 0,               quint16 * port = 0)
参数:
   data: 接收数据的缓存地址
   maxSize: 缓存接收的最大字节数
   address: 数据发送方的地址(一般使用提供的默认值)
   port: 数据发送方的端口号(一般使用提供的默认值)
使用pendingDatagramSize()可以获取到将要接收的数据的大小,根据该函数返回值来准备对应大小的内存空间存放将要接收的数据。
   发送数据:
使用writeDatagram()函数发送数据,函数声明如下:
qint64 writeDatagram(const QByteArray & datagram,
           const QHostAddress & host,                     quint16 port)
参数:
   datagram:要发送的字符串
   host:数据接收方的地址
   port:数据接收方的端口号

再来了解一下组播和广播的区别:
广播:
  在使用QUdpSocket类的writeDatagram()函数发送数据的时候,其中第二个参数host应该指定为广播地址:QHostAddress::Broadcast此设置相当于QHostAddress(“255.255.255.255”)
使用UDP广播的的特点:
   使用UDP进行广播,局域网内的其他的UDP用户全部可以收到广播的消息
   UDP广播只能在局域网范围内使用

组播:
  我们再使用广播发送消息的时候会发送给所有用户,但是有些用户是不想接受消息的,这时候我们就应该使用组播,接收方只有先注册到组播地址中才能收到组播消息,否则则接受不到消息。另外组播是可以在Internet中使用的。在使用QUdpSocket类的writeDatagram()函数发送数据的时候,其中第二个参数host应该指定为组播地址,关于组播地址的分类:
   224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
   224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
   224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
   239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。

这里做了一个udp的小例子,一个发送端一个接收端,接收端只有接收数据功能,没有添加发送功能,接收端可以使用组播接收或者广播接收。
udp发送端cpp:

#include "udpwidget.h"
#include "ui_udpwidget.h"

udpWidget::udpWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::udpWidget)
{
    ui->setupUi(this);
    setWindowTitle("数据发送端");
   m_udpsocket =NULL;
   m_udpsocket = new QUdpSocket(this);

}

udpWidget::~udpWidget()
{
    delete ui;
}

void udpWidget::on_pushButton_clicked()
{
    //获取combox里面的选择,可以通过index或者文本方式解析
    qint32 index =  ui->comboBox->currentIndex();

    qDebug()<<QString("当前combox选择的为%1").arg(index);
    qDebug()<<"当前combox选择的为:"<< ui->comboBox->currentText();

    //从textedit中获取待发送的信息
    QByteArray array = ui->textEdit->toPlainText().toUtf8();  //把string类型转成QByteArray类型

    switch (index) {
    case 0:
        //单播
        m_udpsocket->writeDatagram(array,QHostAddress("192.168.137.1"),6677);

        break;
    case 1:
        //组播 组播ip地址范围:224.0.0.0-----239.255.255.255
        m_udpsocket->writeDatagram(array,QHostAddress("224.0.0.100"),6677);
        break;
    case 2:
        //广播 QHostAddress::Broadcast
         m_udpsocket->writeDatagram(array,QHostAddress::Broadcast,6677);
        break;
    default:
        return;
        break;
    }

}

udp接收端cpp:

#include "udprev.h"
#include "ui_udprev.h"
#include <QUdpSocket>
#include <QComboBox>

udprev::udprev(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::udprev)
{
    ui->setupUi(this);

    setWindowTitle("数据接收端");
   m_udpsocket = new QUdpSocket();

    //在udp中如果需要接受数据 需要绑定套接字,只发送数据则不需要
    m_udpsocket->bind(QHostAddress::AnyIPv4,6677); //任意网口 6677端口和发送数据端口保持一致

    //监听readyread信号
    connect(m_udpsocket,&QUdpSocket::readyRead,this,&udprev::Deal_RevData);


}

udprev::~udprev()
{
    delete ui;
}

void udprev::Deal_RevData()
{
    //读取数据
    QByteArray array;
    array.resize(m_udpsocket->bytesAvailable());  //m_udpsocket->bytesAvailable()可以获取到当udp包的大小
    m_udpsocket->readDatagram(array.data(),array.size());
    //显示在窗口上
    ui->textEdit->append(array);

}

void udprev::on_checkBox_clicked()
{
    //判断是否加入组播
    if(ui->checkBox->isChecked() == true)
    {
        //加入组播
        m_udpsocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
        qDebug()<<"加入组播";
    }else
        {
            //退出组播
            m_udpsocket->leaveMulticastGroup(QHostAddress("224.0.0.100"));
        }
}

最终实验结果:
在这里插入图片描述
这个例子只能单端发送 ,我们只是梳理下udp的流程,具体功能还需要自己去添加。我试了一下,双向通信、
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值