赞
踩
首先,UDP通信是无连接的,虽然不可靠但是传输效率高,UDP就像是写信,知道地址即可,TCP就像是打电话,确保目标正确。
在UDP服务器端,通信套接字直接绑定,如果对方发数据,套接字自动触发readyRead(),发是通过槽函数实现。
在UDP客户端,通信套接字直接绑定,如果对方发数据,套接字自动触发readyRead(),发是通过槽函数实现。
实际上,UDP并不着重区分客户端与服务器端,两者都是只需要一个通信套接字,并不需要监听,当通信套接字的readyRead信号有效之后自动读取。
读取:
首先是获取发送方的IP地址,通过通信套接字中的readDatagram()函数来实现,传入的参数:
qint64 QUdpSocket::readDatagram(char*data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)
Receives a datagram no larger than maxSize bytes and stores it in data.The sender’s host address and port is stored in *address and *port(unless the pointers are 0).
Returns the size of the datagram on success; otherwise returns -1.
根据函数介绍可知,函数的第一个传入参数为用于存储接收数据的变量地址,形参为char 表明传入参数应为一个地址。
第二个参数为接收缓冲区的大小,
第三个参数为主机IP,格式为QhostAddress,所以应该传入一个该类型的变量地址。
第一个参数为端口号,格式为uint16,同样传入一个该类型的变量地址,
#------------------------------------------------- # # Project created by QtCreator 2020-2-17T15:03:16 # #------------------------------------------------- QT += core gui #添加网络模块 QT += network CONFIG += C++11 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = 07_Udp TEMPLATE = app SOURCES += main.cpp\ widget.cpp HEADERS += widget.h FORMS += widget.ui
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QUdpSocket> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: /** * @brief readUdpData udp接收数据槽函数 */ void readUdpData(); private slots: /** * @brief on_pushButtonBind_clicked 绑定按键 */ void on_pushButtonBind_clicked(); /** * @brief on_pushButtonSend_clicked 发送按键 */ void on_pushButtonSend_clicked(); /** * @brief on_pushButton_2_clicked 关闭按键 */ void on_pushButton_2_clicked(); private: Ui::Widget *ui; QUdpSocket *udpSocket; //套接字指针,#include <QUdpSocket> }; #endif // WIDGET_H
#include "widget.h" #include "ui_widget.h" #include <QMessageBox> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //设置发送按钮状态 ui->pushButtonSend->setEnabled(false); //指定父对象目录,为了自动回收空间 udpSocket = new QUdpSocket(this); //加入组播 //udpSocket->joinMulticastGroup(QHostAddress("224.0.0.100")); //退出组播 //udpSocket->leaveMulticastGroup(QHostAddress("224.0.0.100")); //数据响应信号槽函数 connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readUdpData())); //connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::readUdpData); } Widget::~Widget() { delete ui; } void Widget::readUdpData() { // QByteArray array; // array.resize(mSocket->bytesAvailable());//根据可读数据来设置空间大小 char buf[1024] = {0}; QHostAddress addr; quint16 port; //读取数据,addr为网络地址,port为端口 udpSocket->readDatagram(buf, sizeof(buf), &addr, &port); QString str = QString("[%1:%2]%3").arg( addr.toString() ).arg(port).arg(buf); ui->textEdit->append(str);//给编辑区设置内容 //设置对方的网络信息 ui->lineEditIP->setText(addr.toString()); ui->lineEditOtherPort->setText(QString::number(port)); } //绑定按钮 void Widget::on_pushButtonBind_clicked() { QString str = ui->lineEditMyPort->text(); bool isOk = udpSocket->bind(QHostAddress::AnyIPv4,/*8007*/str.toShort()); //bool isOk = udpSocket->bind(str.toShort()); //绑定端口同上 if(false == isOk) { QMessageBox::warning(this, "警告", "绑定端口失败"); return; } ui->pushButtonBind->setEnabled(false); ui->pushButtonSend->setEnabled(true); } //发送按钮 void Widget::on_pushButtonSend_clicked() { QString ip = ui->lineEditIP->text(); //获取对方ip short port = ui->lineEditOtherPort->text().toShort(); //获取对方端口 //QString str = ui->textEdit->toPlainText(); //获取发送内容 QString str = ui->textEdit_2->toPlainText(); //发送信息 udpSocket->writeDatagram(str.toUtf8(), QHostAddress(ip), port); ui->textEdit->append(QString("%1: %2").arg("我").arg(str)); //把发送的内容添加到聊天记录中 ui->textEdit_2->clear(); //单播 //qint64 len = udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),8007/*port*/); //组播ip地址范围:224.0.0.0-239.255.255.255 //qint64 len = udpSocket->writeDatagram(str.toUtf8(),QHostAddress("224.0.0.100"),6677/*port*/); //广播 //qint64 len = udpSocket->writeDatagram(str.toUtf8(), QHostAddress::Broadcast, 8007/*port*/); } //关闭按钮 void Widget::on_pushButton_2_clicked() { udpSocket->close(); this->close(); }
欢迎大家关注作者在文末评论、点赞、转发以及批评指正!
如果大家有更好的方法或有问题可以在文末评论一起讨论!
共同学习!
共同进步!
人这一生会说上万个谎言,最容易脱口而出的那个是:没事,我很好。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。