Qt网络-UDP,QUdpSocket,单播和广播程序实现(二)

核心代码

1. 绑定端口

要接收UDP数据报,必须绑定一个端口,来监听数据传入。

//绑定端口
void bindPort()
{
    quint16 port = ui->spinBindPort->value(); // 本机UDP端口
    if (udpSocket->bind(port)) // 绑定端口成功
    {
        ui->plainTextEdit->appendPlainText("**已成功绑定");
        ui->plainTextEdit->appendPlainText("**绑定端口:" + QString::number(udpSocket->localPort()));
        ui->actStart->setEnabled(false);
        ui->actStop->setEnabled(true);
    }
    else
        ui->plainTextEdit->appendPlainText("**绑定失败");
}

2. 解绑端口

//解除绑定
void unbind()
{
    udpSocket->abort(); // 解除绑定
    ui->actStart->setEnabled(true);
    ui->actStop->setEnabled(false);
    ui->plainTextEdit->appendPlainText("**已解除绑定");
}

3. 发送数据

单播和广播发送消息都使用writeDatagram()函数,区别是单播向一个目标发送数据时需要指定目标IP和端口,广播时只需要将目标地址更换为一个特殊的地址,即广播地址QHostAddress::Broadcast。

// 发送消息 按钮
void MainWindow::on_btnSend_clicked()
{
    QString targetIP = ui->comboTargetIP->currentText(); //目标IP
    QHostAddress targetAddr(targetIP);

    quint16 targetPort = ui->spinTargetPort->value();//目标port

    QString msg = ui->editMsg->text();//发送的消息内容

    QByteArray str = msg.toUtf8();
    udpSocket->writeDatagram(str,targetAddr,targetPort); //发出数据报

    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();
}
 // 广播消息 按钮
void MainWindow::on_btnBroadcast_clicked()
{
    quint16 targetPort=ui->spinTargetPort->value(); //目标端口
    QString msg=ui->editMsg->text();
    QByteArray str=msg.toUtf8();
    udpSocket->writeDatagram(str,QHostAddress::Broadcast,targetPort);

    ui->plainTextEdit->appendPlainText("[broadcast] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();
}

4. 接收数据

QUdpSocket接收到数据报后发射readyRead()信号,可以实现槽函数来读取缓冲区的数据。

// 读取收到的数据报
void MainWindow::onSocketReadyRead()
{
    while(udpSocket->hasPendingDatagrams())  // 判断是否有待读取的数据
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize()); // 获取待读取数据报的字节数

        QHostAddress peerAddr;
        quint16 peerPort;
        udpSocket->readDatagram(datagram.data(),datagram.size(),&peerAddr,&peerPort); // 读取数据报内容
        QString str=datagram.data();

        QString peer="[From "+peerAddr.toString()+":"+QString::number(peerPort)+"] ";

        ui->plainTextEdit->appendPlainText(peer+str);
    }
}

注意:qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)
函数中data和maxSize是必须的,maxSize指定最多读取多少字节数据到data中,address和port是可选的,可以获取数据包来源的IP地址和端口。示例中传输字符串,不需要做特殊处理,如果是自定义的其他格式,就需要对接收到的数据另做解析。

5. 程序流程

单播:若两个程序在同一台设备运行,程序A绑定端口1000,程序B绑定端口2000,那么想要互相发送消息,就需要将对方的IP地址和端口设置为目标IP和端口。
若两个程序在不同设备运行,那么两个程序可以绑定相同的端口,此时IP地址不同了,不会导致绑定冲突。一般的UDP程序都是在不同设备上运行,约定一个固定端口作为通信端口。
广播:发送者向指定端口发送数据,不在乎IP地址。所有在同一网络范围的绑定了指定端口的UDP客户端都能收到数据。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorAL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值