一。Udp详细解释
UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP相比,UDP不提供可靠性、流量控制、拥塞控制和错误恢复等功能,但由于其简单性和低开销,UDP在一些特定的应用场景中得到广泛应用。
UDP的特点如下:
- 无连接:UDP在通信之前不需要建立连接,发送方直接将数据报发送给接收方。
- 不可靠:UDP不保证数据报的可靠传输,数据报可能会丢失、重复或乱序。
- 高效:由于不需要建立连接和维护状态信息,UDP的开销较小,传输效率较高。
- 面向报文:UDP将应用层交给它的数据报作为一个整体进行处理,不会对数据进行拆分和合并。
UDP适用于以下场景:
- 实时性要求高:由于UDP不需要建立连接和维护状态信息,可以更快地传输数据,适用于实时性要求较高的应用,如音视频传输、实时游戏等。
- 数据量小、频繁:由于UDP不提供流量控制和拥塞控制等机制,适用于数据量小、频繁发送的场景,如DNS查询、SNMP等。
- 可靠性由应用层保证:在某些应用中,可靠性要求由应用层自身保证,如实时语音通信中的重传机制。
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() { }