博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt开发的UDP发送端
阅读量:5972 次
发布时间:2019-06-19

本文共 6227 字,大约阅读时间需要 20 分钟。

hot3.png

    一、准备

    (一)开发环境

    系统:Windows 7 专业版(64位)

    软件:qt-opensource-windows-x86-mingw530-5.7.0(原来用Qt 5.2.1+完成的工程)

    注:Qt下载链接http://download.qt.io/official_releases/qt/

    (二)知识准备

    Qt 5入门请看书籍《C++ Qt5 范例开发大全 》(可通过网络搜索,也可以通过Qt交流QQ群获得)。

    Qt创建工程请看百度教程:http://jingyan.baidu.com/article/7908e85c95d538af491ad274.html

    网络传输协议知识,请自行脑补!

    二、开发过程

    (一)创建Qt 工程,命名udpEndpoint1(任何名字都可以,只要符合Qt文件命名规则)

    创建没有严格按照步骤一步步来,就点一下关键的地方。

    1. 选择QWidget基类

    192547_e35e_2936888.png

    2. 创建完成

    192908_IfJb_2936888.png

    (二)打开udpEndpoint1.pro,找到代码行,就在正文第一行

QT       += core gui

    右边加上“network”,这一步非常重要,这样才能加载Qt中与网络有关的库(这是我自己的理解,不专业),不然后面程序运行会报错。修改如下:

QT       += core gui network

    注:请注意一下.pro的内容和工程文件中头文件和源文件下的文件,后文中会用到。

    (三)创建一个新类(类名:udpSender

    创建类的步骤:

    1. 点击:文件 --> 新建文件或项目,进入界面如下

    194512_LFVA_2936888.png

    2. 选择:文件和类 --> C++

    194345_VnYa_2936888.png

    3. 选择C++ Class,进入界面如下图

    195014_URLF_2936888.png

    4. 类名:udpSender,基类(Base Class):QObject,类存放路径一定要保证存在main.c所在的路径下(之前我创建在其他路径,工程文件里不出现类定义文件:.cpp和.h)

    195728_SVWM_2936888.png

    5.一路“下一步”,直到完成

    195927_hC1j_2936888.png

    头文件里就多了个udpsender.h,源文件里也多了个udpsender.cpp。再看.pro文件内容,SOURCES下面多了一个udpsender.cpp;HEADERS,下面也多了个udpsender.h

SOURCES += main.cpp\        widget.cpp \    udpsender.cppHEADERS  += widget.h \    udpsender.h

    (四)定义类文件

    1.打开udpsender.h,修改代码为:

//udpsender.h#ifndef UDPSENDER_H#define UDPSENDER_H#include 
#include
#include
#include
class udpSender : public QObject{ Q_OBJECTpublic: explicit udpSender(QObject *parent = 0); udpSender(QString recv_host,quint16 recv_port,quint16 port); ~udpSender(); void setReceiverHost(QString host);//设置接收端的socket地址 void setReceiverPort(quint16 port);//设置接收端的socket端口 void setReceiverAddress(QString host,quint16 port); //设置接收端的socket地址和端口 void setSenderPort(quint16 port); //设置发送端socket端口 void udpSocketBindUpdate(); //更新socket绑定的端口号,端口号就是设置的发送端socket端口 void sendDatagram(QByteArray datagram); //数据发送private: QUdpSocket *udpSocket; //socket对象 QHostAddress *receiver_host; //接收端的IP地址 quint16 sender_port,receiver_port; //发送端端口,接收端端口signals:public slots:};#endif // UDPSENDER_H

    2.打开udpsender.cpp,修改代码

//udpsender.cpp#include "udpsender.h"udpSender::udpSender(QObject *parent) :    QObject(parent){    udpSocket = new QUdpSocket(this);    receiver_host = new QHostAddress("127.0.0.1");    receiver_port = -1;    sender_port = -1;}udpSender::udpSender(QString recv_host,quint16 recv_port,quint16 port){    udpSocket = new QUdpSocket(this);    receiver_host = new QHostAddress(recv_host);    receiver_port = recv_port;    sender_port = port;}void udpSender::setReceiverHost(QString host){    receiver_host->setAddress(host);}void udpSender::setReceiverPort(quint16 port){    receiver_port = port;}void udpSender::setReceiverAddress(QString host,quint16 port){    setReceiverHost(host);    setReceiverPort(port);}void udpSender::setSenderPort(quint16 port){    sender_port = port;}void udpSender::udpSocketBindUpdate(){    udpSocket->abort();    udpSocket->bind(sender_port);}void udpSender::sendDatagram(QByteArray datagram){    udpSocket->writeDatagram(datagram,*receiver_host,receiver_port);}udpSender::~udpSender(){    udpSocket->close();}

    到此,类文件定义完毕!

(五)ui设计

打开界面文件widget.ui,设计如下界面

202211_ooKM_2936888.png

控件的属性如下:

控件标记 控件类型 控件名称(objectName)
1 QLineEdit dest_ip
2 QLineEdit dest_port
3 QLineEdit lineEdit
4 QTextEdit textEdit
目标IP地址、目标端口 QLabel *
指定发送端口、发送数据 QLabel *
发送 QPushButton pushButton
清空 QPushButton pushButton_2

ui界面设置信号和槽

pushButton_2,也就是“清空”按钮,产生信号click(),连接到textEdit,也就是编号为4的编辑框,槽函数为clear()

(六)编辑Widget代码

1. 打开widge.h,编辑如下:

//widge.h#ifndef WIDGET_H#define WIDGET_H#include 
#include
namespace Ui {class Widget;}class Widget : public QWidget{ Q_OBJECTpublic: udpSender *sender; explicit Widget(QWidget *parent = 0); ~Widget(); quint16 getRecvPortInput(); //接收编辑框输入-->接收端socket端口 QString getRecvHostInput(); //接收编辑框输入-->接收端socket地址 quint16 getSendPortInput(); //接收编辑框输入-->发送端socket端口 QByteArray getDataInput(); //获取待发送数据输入public slots: void on_pushButton_clicked(); //发送按钮槽函数private: Ui::Widget *ui;};

    2. 打开widge.cpp,编辑代码如下:

//widge.cpp#include "widget.h"#include "ui_widget.h"#include "QtNetwork"#include "QMessageBox"QRegExp regExpIP("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])[\\.]){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");QRegExp regExpNetPort("((6553[0-5])|[655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])");Widget::Widget(QWidget *parent) :    QWidget(parent),    ui(new Ui::Widget){    ui->setupUi(this);    this->setWindowTitle("UDP发送端");    ui->dest_port->setValidator\            (new QRegExpValidator(regExpNetPort,this));    ui->lineEdit->setValidator\            (new QRegExpValidator(regExpNetPort,this));    ui->dest_ip->setValidator(new QRegExpValidator(regExpIP,this));    sender = new udpSender();}QString Widget::getRecvHostInput(){    return ui->dest_ip->text();}quint16 Widget::getRecvPortInput(){    quint16 dest_port;    QString inputDestPort = ui->dest_port->text();    if(inputDestPort.isEmpty())        dest_port = -1;    else        //QString 文本输入,转换为quint16的数字端口        dest_port = inputDestPort.toUInt();    return dest_port;}//指定发送端口quint16 Widget::getSendPortInput(){    quint16 sourcePort;    QString inputSourcePort = ui->lineEdit->text();    if(inputSourcePort.isEmpty())        sourcePort = -1;    else        //QString 文本输入,转换为quint16的数字端口        sourcePort = inputSourcePort.toUInt();    return sourcePort;}QByteArray Widget::getDataInput(){    //处理文本输入    QString text = ui->textEdit->toPlainText();    QByteArray datagram = text.toUtf8(); //中文编码    return datagram;}Widget::~Widget(){    delete ui;}//发送void Widget::on_pushButton_clicked(){    sender->setSenderPort(getSendPortInput());    sender->setReceiverHost(getRecvHostInput());    sender->setReceiverPort(getRecvPortInput());    sender->udpSocketBindUpdate();    sender->sendDatagram(getDataInput());}

main.cpp的代码不用修改,为了方便科友查看,也把它放出来。

//main.cpp#include "widget.h"#include 
int main(int argc, char *argv[]){ QApplication a(argc, argv); Widget w; w.show(); return a.exec();}

(七)运行程序

点击运行按钮,运行结果如下:

225330_GKNw_2936888.png

实例

我要用本机的udp socket的8082口发送数据到另一台主机(IP: 10.106.10.203,PORT:8083),发送数据为:Hello,很高兴认识你。

输入界面如下:

225740_9TNq_2936888.png

到此为止,udp发送端的程序开发已经完成,udp接收端将在后续的博客中再谈。

此帖重在交流,如有问题,请QQ联系:1592017939,水平有限,请多指正!

转载于:https://my.oschina.net/marshal2bit/blog/803803

你可能感兴趣的文章
中文乱码总结
查看>>
TypeScript VS JavaScript 深度对比
查看>>
Java的Executor框架和线程池实现原理
查看>>
推荐vue.js、layer.js、axios.js
查看>>
14.MongoDBUtils工具类
查看>>
java.lang.NoClassDefFoundError: Could not initialize class com.demo.jdbc.utils.MyJdbcUtils
查看>>
关于centos6升级python3.6无法使用pip的问题
查看>>
其他排序
查看>>
小程序笔记三:幻灯片swiper 和图片自定义高度
查看>>
时间操作(JavaScript版)—页面显示格式:年月日 上午下午 时分秒 星期
查看>>
5分钟弄懂:语音识别技术原理
查看>>
Android Studio_更新Gradle
查看>>
leetcode 258. Add Digits——我擦,这种要你O(1)时间搞定的必然是观察规律,总结一个公式哇...
查看>>
[100]tar命令打包(排除目录或文件)
查看>>
查询应用服务器的会话数
查看>>
netty 源码分析
查看>>
浅谈ST表
查看>>
Android BLE 总结-源码篇(BluetoothLeAdvertiser)
查看>>
不完整类型
查看>>
Linux C++ 访问子目录以及里面的文件
查看>>