赞
踩
本例程已在单台机器和路由器下的多台机器上测试成功。
只支持文本发送,如果特殊的数据类型比如结构体、表格发送还得另定义编码与解析。
代码在文章末尾。点击跳转
1、引入与UDP通信相关的库和功能;
2、头文件中声明通信相关的对象udpSocket和按键绑定函数等;
3、定义函数内容:
[3.1]按键绑定函数中为读取目标端口、目标IP与发送内容的功能;
[3.2]再用UdpSocket库的功能进行发送。
[跳转到接收端]
1、引入与UDP通信相关的库和功能;
2、头文件中声明通信相关的对象udpSocket、按键绑定函数和接收处理函数等;
3、定义函数内容:
[3.1]读取端口号与IP地址,绑定端口,验证端口绑定成功;
[3.2]定义接收处理函数,与事件“接收到信号”进行绑定,每次接收到数据便执行此函数。
其中,上方的PlainTextEdit组件是数据发送的输入框;下方的PlainTextEdit组件是信息输出框;
端口号输入框使用QSpinBox组件,IP输入框使用QLineEdit组件。
具体实现代码我会放在文末,[点击跳转]下面对关键部分代码做以下解释。
QT += network
这样,在头文件中就可以包含与UDP通信相关的库了:
#include <QUdpSocket>
namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_pushButton_clicked(); private: Ui::Widget *ui; QUdpSocket *udpSocket;// QString getLocalIP();//获取本机IP地址 }; #endif // WIDGET_H
其中,有一个按键的绑定函数,一个QUdpSocket的指针对象,还有一个获取本机IP的函数。
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QString localIP=getLocalIP();//本机IP
this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
udpSocket=new QUdpSocket(this);//用于与连接的客户端通讯的QTcpSocket
}
Widget::~Widget()
{
udpSocket->abort();
delete udpSocket;
delete ui;
}
void Widget::on_pushButton_clicked() { QString targetIP=ui->lineEdit->text(); QHostAddress targetAddr(targetIP); //目标IP quint16 targetPort = ui->spinBox->value(); //目标端口号 QString msg = ui->plainTextEdit->toPlainText(); //发送内容 QByteArray str = msg.toUtf8(); udpSocket->writeDatagram(str, targetAddr, targetPort); //发送函数 ui->window->appendPlainText("[send]" + msg); //信息栏显示 ui->plainTextEdit->clear(); ui->plainTextEdit->setFocus(); }
QString Widget::getLocalIP() { QString hostName=QHostInfo::localHostName();//本地主机名 QHostInfo hostInfo=QHostInfo::fromName(hostName); QString localIP=""; QList<QHostAddress> addList=hostInfo.addresses();// if (!addList.isEmpty()) for (int i=0;i<addList.count();i++) { QHostAddress aHost=addList.at(i); if (QAbstractSocket::IPv4Protocol==aHost.protocol()) { localIP=aHost.toString(); break; } } return localIP; }
其中,目标端口使用的是QSpinBox组件,目标IP使用的是QLineEdit组件,接受框用PlainTextEdit组件。
QT += network
#include <QUdpSocket>
namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private: Ui::Widget *ui; QUdpSocket *udpSocket;// QString getLocalIP();//获取本机IP地址 private slots: void onSocketReadyRead();//读取socket传入的数据 void on_pushButton_clicked(); }; #endif // WIDGET_H
与发送端的构成类似,信号函数多了一个读取socket传入的数据函数:void onSocketReadyRead()
由于接收端需要适时监听端口号收到的信息,因此需要将readyRead()信号与自定义的信号读取函数onSocketReadyRead()关联。
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); QString localIP=getLocalIP();//本机IP this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP); udpSocket=new QUdpSocket(this);//用于与连接的客户端通讯的QTcpSocket connect(udpSocket,SIGNAL(readyRead()), this,SLOT(onSocketReadyRead())); // udpSocket=new QUdpSocket(this);//用于与连接的客户端通讯的QTcpSocket // connect(udpSocket,SIGNAL(readyRead()), // this,SLOT(onSocketReadyRead())); }
Widget::~Widget()
{
udpSocket->abort();
delete udpSocket;
delete ui;
}
void Widget::on_pushButton_clicked()
{
quint16 port = ui->spinBox->value(); //本机UDP端口
if (udpSocket->bind(port)) //绑定端口成功
{
ui->plainTextEdit->appendPlainText("**成功绑定端口");
ui->plainTextEdit->appendPlainText("**绑定端口:" +
QString::number(udpSocket->localPort())); }
}
void Widget::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(); //数据转换为QT的ui界面使用的QString类型 QString peer="[From "+peerAddr.toString()+":" +QString::number(peerPort)+"] "; ui->plainTextEdit->appendPlainText(peer+str); } }
QString Widget::getLocalIP() { QString hostName=QHostInfo::localHostName();//本地主机名 QHostInfo hostInfo=QHostInfo::fromName(hostName); QString localIP=""; QList<QHostAddress> addList=hostInfo.addresses();// if (!addList.isEmpty()) for (int i=0;i<addList.count();i++) { QHostAddress aHost=addList.at(i); if (QAbstractSocket::IPv4Protocol==aHost.protocol()) { localIP=aHost.toString(); break; } } return localIP; }
IP查询可以cmd到终端输入ipconfig查询。
端口号绑定不成功的话换一个数字重试,可能与计算机已经占用的端口发生了冲突,一般选择时尽量选择大一些的端口号避免冲突。
不要开串口调试工具同时进行调试,使用时应该断开串口调试共苦,原因就是上一点的串口冲突问题。
单机测试使用时,开两个QT应用,发送和接收程序都运行,先根据自己电脑的IP地址设置号IP,端口号保持一致。在接收端点击绑定端口,端口绑定成功后会有提示,再到发送端发送自己像发送的内容,图片中发送的Hello已经成功接收到。
多机使用时,保证IP处于同一网段,接收端和发送端端口设置一致,IP使用接收端电脑的IP地址。
❤️跳转过来啦❤️
链接:https://pan.baidu.com/s/1VrwGKHWd2RRv_PNu7tUZvg
提取码:pkci
https://github.com/FLBa9762/Qt-UdpSocket-Code.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。