【QT学习】UDP协议,广播,组播

发布于:2024-04-30 ⋅ 阅读:(19) ⋅ 点赞:(0)

一。Udp详细解释

UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP相比,UDP不提供可靠性、流量控制、拥塞控制和错误恢复等功能,但由于其简单性和低开销,UDP在一些特定的应用场景中得到广泛应用。

UDP的特点如下:

  1. 无连接:UDP在通信之前不需要建立连接,发送方直接将数据报发送给接收方。
  2. 不可靠:UDP不保证数据报的可靠传输,数据报可能会丢失、重复或乱序。
  3. 高效:由于不需要建立连接和维护状态信息,UDP的开销较小,传输效率较高。
  4. 面向报文:UDP将应用层交给它的数据报作为一个整体进行处理,不会对数据进行拆分和合并。

UDP适用于以下场景:

  1. 实时性要求高:由于UDP不需要建立连接和维护状态信息,可以更快地传输数据,适用于实时性要求较高的应用,如音视频传输、实时游戏等。
  2. 数据量小、频繁:由于UDP不提供流量控制和拥塞控制等机制,适用于数据量小、频繁发送的场景,如DNS查询、SNMP等。
  3. 可靠性由应用层保证:在某些应用中,可靠性要求由应用层自身保证,如实时语音通信中的重传机制。

2.如何写Udp的代码(qt中)

        UDP是一种半双工通信协议,这意味着它在同一时间只能进行发送或接收操作,而不能同时进行发送和接收。当一个主机使用UDP发送数据时,它不能立即接收来自同一主机的响应数据。相反,它必须等待发送完成后才能接收数据。

        因此,UDP不支持全双工通信,而是通过交替的发送和接收操作来实现数据传输。全双工通信需要使用其他协议,如TCP,它提供了可靠的、面向连接的双向数据传输。

二。实例:使用QT写Udp代码

结果:

        相互通信正常,服务器中对方端口是通过观察:收来的数据来判断对方port

服务器端

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务器端,port:8888");

    //创建socket
    pUdpSocket=new QUdpSocket(this);
    //绑定服务器端的端口
    pUdpSocket->bind(8888);
    //设置  组播 进组  《组播使用》
    //pUdpSocket->bind(QHostAddress::AnyIPv4,8888);
    //pUdpSocket->joinMulticastGroup(QHostAddress("224.0.0.3"));

    //收数据
    connect(pUdpSocket,&QUdpSocket::readyRead,
            [=](){
        char buff[1024] = {0};  //为读数据做准备
        QHostAddress ip;        //为读数据做准备
        quint16 port;           //为读数据做准备
        pUdpSocket->readDatagram(buff,1023,&ip,&port);//读数据

        QString str = QString("ip:%1,port:%2,msg:%3").arg(ip.toString()).arg(port).arg(buff);
        ui->textEditRECV->append(str);
    });
}

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


void Widget::on_pushButtonCLOSE_clicked()
{

}

void Widget::on_pushButtonSEND_clicked()
{
    QString ip=ui->lineEditIP->text();
    QString port=ui->lineEditPORT->text();
    QString msg=ui->textEditSEND->toPlainText();
    pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
    /*
writeDatagram(      函数名
msg.toUtf8()        textEditSEND内容改为UTF-8类型,这样展示正确
QHostAddress(ip)    ip强制转换为QHostAddress
port.toUInt()       port强制转换为int
);
*/
}

客户端

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
    this->setWindowTitle("客户端");
    //创建对象
    pUdpSocket=new QUdpSocket(this);
    //收数据-->与服务器端处理一模一样,代码都一样
    connect(pUdpSocket,&QUdpSocket::readyRead,
            [=](){
        char buff[1024] = {0};  //为读数据做准备
        QHostAddress ip;        //为读数据做准备
        quint16 port;           //为读数据做准备
        pUdpSocket->readDatagram(buff,1023,&ip,&port);//读数据

        QString str = QString("ip:%1,port:%2,msg:%3").arg(ip.toString()).arg(port).arg(buff);
        ui->textEditRECV->append(str);
    });
}

Form::~Form()
{
    delete ui;
}
//与服务器代码一样
void Form::on_pushButtonSEND_clicked()
{
    QString ip=ui->lineEditIP->text();
    QString port=ui->lineEditPORT->text();
    QString msg=ui->textEditSEND->toPlainText();
    pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}

void Form::on_pushButtonCLOSE_clicked()
{

}