QT编写TCP/UDP调试助手之UDP通信

效果图:

 QT编写TCP/UDP调试助手之UDP通信,支持单播、组播和广播三种通信模式。

一、前言

UDP(用户数据报协议)是一种简单轻量级、不可靠、面向数据报,无连接的传输层协议,也就是发送数据前不需要握手连接,只要知道IP和端口号就能发送数据,但是对方能不能收到,收到的对不对就不得而知了。

UDP通信中分为三种通信方式,分别为单播、组播和广播,主要就是IP的区别。

二、关键代码

1.在.pro文件中添加QT += network,包含头文件#include <QUdpSocket>

在类里定义一个QTcpSocket*成员m_udpSocket

 

2.界面校验设置。界面上有四个lineEdit用来填写IP和端口,通过setValidator可以限制lineEdit输入的范围,端口号范围0-65535,IP地址用正则表达式校验,防止输入错误。

 //设置端口输入校验
    ui->lineEdit_udpLocalPort->setValidator(new QIntValidator(0,65535));
    ui->lineEdit_udpRemotePort->setValidator(new QIntValidator(0,65535));
    //ip校验正则
    QRegExp regExpIP("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])[\\.]){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");
    //设置IP输入校验
  ui->lineEdit_udpLocalIP->setValidator(new QRegExpValidator(regExpIP ,ui->lineEdit_udpLocalIP));
    ui->lineEdit_udpRemoteIP->setValidator(new QRegExpValidator(regExpIP ,ui->lineEdit_udpRemoteIP));

3.绑定端口,绑定端口后收到数据时会发射readyRead()信号

        //绑定端口
        this->m_udpSocket->bind(localip,port,QAbstractSocket::ShareAddress);
        //连接接收信号槽
        connect(m_udpSocket,SIGNAL(readyRead()),this,SLOT(UdpReadData()));

4.接收数据槽函数,注意和TcpSocket不同,不是直接调用readAll()

//udp接收消息
void MainWindow::UdpReadData()
{
    //获取发来的数据
    QByteArray datagram;
    while (m_udpSocket->hasPendingDatagrams())
    {
        //等待接收的字节数
        int sizeLen=static_cast<int>(m_udpSocket->pendingDatagramSize());
        datagram.resize(sizeLen);
        //读取
        m_udpSocket->readDatagram(datagram.data(),datagram.size());
    }
    QString data;
    //hex
    if(ui->chk_udpRecHex->isChecked())
    {
        this->ByteToHexString(data,datagram);
    }
    else//普通字符串
    {
        data=QString::fromLocal8Bit(datagram);
    }
    //显示
    ui->text_udpRec->insertPlainText(data);
    ui->text_udpRec->moveCursor(QTextCursor::End);
}

5.选择组播通信模式时,可以勾选加入组播,接收组播数据。

组播是udp实现一对多通信的一种方式,一个udp客户端往该IP发消息,加入该组的客户端都会收到消息。组播IP地址为D类地址,范围224.0.0.0~239.255.255.255。

5.1判断IP地地址在224.0.0.0~239.255.255.255范围内

   //获取组播Ip
        bool ok;
        QHostAddress groupip(ui->lineEdit_GroupIp->text());
        groupip.toIPv4Address(&ok);
        if(!ok)
        {
            QMessageBox::warning(this,"错误","组播IP输入有误,请重新输入");
            ui->chk_udpGroup->setChecked(false);
            return;
        }        
//D类IP地址的范围为224.0.0.0~239.255.255.255。前4比特固定为1110,后28比特是组播组地址标识(ID)
        QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet("224.0.0.0/4");
        bool is_DClass = groupip.isInSubnet(subnet);
        if(!is_DClass)
        {
            QMessageBox::warning(this,"错误","组播IP应在D类IP地址范围224.0.0.0~239.255.255.255内,请重新输入");
            ui->chk_udpGroup->setChecked(false);
            return;
        }

5.2加入\退出组播IP组,加入后有数据会发射readyRead()信号,就能接收数据了

      //加入组
        m_udpSocket->joinMulticastGroup(groupip);
        //退出组
        m_udpSocket->leaveMulticastGroup(currentIP);

 

6.发送数据,调用m_udpSocket->writeDatagram(byteArray,ip,port)发送,单播、组播和广播就是IP不同,这里就体现出来了。

6.1单播:IP地址任意,例如:

     m_udpSocket->writeDatagram(byteArray,QHostAddress("192.168.206.100"),port);

6.2组播:IP是D类地址,范围224.0.0.0~239.255.255.255,有加入组的客户端才会收到数据,例如:

     m_udpSocket->writeDatagram(byteArray,QHostAddress("224.0.0.2"),port);

6.3广播:IP设置为QHostAddress::Broadcast,相当于QHostAddress("255.255.255.255").,广播数据会发送给局域网内的每个客户端,例如:

        m_udpSocket->writeDatagram(byteArray,QHostAddress::Broadcast,port);

7.注意事项

前面都在说IP,其实端口也很重要,端口一定要对应,不然会收不到数据,例如:

7.1组播通信,本地绑定的是192.168.206.1:6666,并加入组播IP 224.0.0.2。对方往224.0.0.2:1234发数据本地是收不到的,因为端口不对,要往224.0.0.2:6666发才收得到。

7.1广播也是如此,writeDatagram(byteArray,QHostAddress::Broadcast,1234);广播发的是1234端口,那局域网内的客户端也必须绑定的是1234端口,才会收到数据。

三、下载

tcp/udp调试助手

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章