IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> QT网络编程——UDP -> 正文阅读

[网络协议]QT网络编程——UDP

一、TCP和UDP编程的区别

1、我们记得TCP网络编程中,要分TCP服务器端和客户端,但是UDP网络编程中,不分客户端和服务器端了,每个用户既是客户端又是服务器端。

2、TCP中需要用到两个类:QTcpSever和QTcpSocket。而UDP中只需要使用一个类QUdpSocket

需要用到本地端口,目标端口,目标IP地址。
其中本地端口:自己为该UDP主机设置的端口号,目的是对方发送数据时,会发到本机此端口上。
目标端口:对方的UDP主机设置的端口号,作用是可以在本机上向某个IP用户的端口上发送数据。

二、QUdpSocket类所用到的接口函数

函数功能
bind(quint16 port)将socket和指定端口号进行绑定
close()关闭这个socket
readyRead()这个是信号,当其它用户向本机的端口上发送数据时,就会产生这个信号。
writeDatagram(QByteArray &datagram, QHostAddress &host, quint16 port)数据报发送,形参分别为数据报,目的IP地址,目的端口号
hasPendingDatagram()socket中有接收到用户发来的数据报时,返回值为true
pendingDatagramSize()返回待读取数据报的大小
readDatagram(char *data, qint64 maxSize)读取数据报,返回读取数据报的字节数,maxSize为设置的读取字节数,还可以加上源IP和源端口号

三、QT中UDP编程思路

1、开启UDP通讯服务:建立QUdpSocket对象,并用其中的bind()方法就可以将套接字和端口号进行绑定。(一但有用户向本主机的这个端口号发送数据,就会产生readyRead信号)

udpSocket->bind(ui->lineEdit_localPort->text().toUInt());

2、在readyRead信号所对应的槽函数中,接收对方发送过来的数据报。
用hasPendingDatagrams()函数,判断是还否有下一个数据报待接收。如果有,就用readDatagram()函数读取指定长度的数据报,并存放在数组中。

udpSocket->readDatagram(byteArray.data(),byteArray.size());```

3、通过writeDatagram()函数向远端IP用户的端口号中发送数据。

udpSocket->writeDatagram(sendbuff.toUtf8().data(),sendbuff.length(),ipAddress,port);

:经过测试发现,创建的socket套接字,不用bind函数绑定端口,也可以直接调用writeDatagram函数,而且能成功发送到目的主机的目的端口上去。但是这样的话,貌似他会随机为该套接字绑定一个端口,这是我们不希望的,所以调试时尽量避免。

四、UDP界面设计

在这里插入图片描述

五、代码实现发送和接收数据

1、在pro文件中添加network模块,并且在widget.h中导入QUdpSocket头文件。

QT       += core gui network

在这里插入图片描述
2、在widget构造函数中创建一个QUDPSocket对象

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    udpSocket = new QUdpSocket(this);
}

3、对打开按钮的点击信号绑定槽函数,并实现bind功能
绑定指定端口后,如果对方发来数据,会收到readyRead信号

void Widget::on_pushButton_openOrStop_clicked()
{
    if(ui->pushButton_openOrStop->text() == "打开")
    {
        //udpSocket->bind(QHostAddress::Any,ui->lineEdit_localPort->text().toUInt());
        //将socket和自己设置的端口号进行绑定,只要有用户(不指定,默认为任意IP地址的用户)向这台主机的指定端口号中发送数据,就会产生readyRead信号。
        if(udpSocket->bind(ui->lineEdit_localPort->text().toUInt()))    //绑定成功返回true
        {
            QMessageBox::information(this,"提示","打开成功");
            connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot()));
            ui->pushButton_openOrStop->setText("关闭");
            ui->label_openOrStop->setStyleSheet("border-image: url(:/picture/open.png);");
        }
        else
            QMessageBox::information(this,"提示","打开失败,请重新尝试");

    }
    else
    {
        //udpSocket->abort();
        udpSocket->close();
        ui->pushButton_openOrStop->setText("打开");
        ui->label_openOrStop->setStyleSheet("border-image: url(:/picture/stop.png);");
    }
}

注:一个打开按钮,我设置了两个功能,即点击一次打开,再次点击为关闭。

4、为readyRead信号绑定的槽函数实现功能,主要是接收发送过来的数据报

void Widget::readyRead_slot()
{
    QByteArray byteArray;
    while(udpSocket->hasPendingDatagrams())     //存在未读取的数据报
    {
        byteArray.resize(udpSocket->pendingDatagramSize());     //将数组的长度设置为待读数据报的大小
        udpSocket->readDatagram(byteArray.data(),byteArray.size());     //读取指定大小的数据,并保存在数组中

        ui->plainTextEdit_receive->appendPlainText(QString(byteArray.data()));      //显示在界面的编辑框中
    }

}

5、实现发送数据的功能

void Widget::on_pushButton_send_clicked()
{
    QHostAddress ipAddress;   //用来存储目标主机IP地址
    quint16 port;               //存储目标主机端口号
    QString sendbuff;       //存储要发送的字符串

    ipAddress.setAddress(ui->lineEdit_aimIp->text());       //将编辑框中的ip地址转换为网络上可以识别的IPv4地址
    sendbuff = ui->lineEdit_send->text();
    port = ui->lineEdit_aimPort->text().toUInt();
    //将指定长度的数据封装称数据报,然后发到IP用户的端口上
    udpSocket->writeDatagram(sendbuff.toUtf8().data(),sendbuff.length(),ipAddress,port);        //向目的IP的目的端口发送指定长度的数据
}

完结!!!!

六、源代码下载

此代码的源码

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:20:18  更:2022-01-01 14:22:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:23:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码