当前位置:   article > 正文

Qt之UDP_如何使用qt实现udp对文件边写边读

如何使用qt实现udp对文件边写边读

概述:

首先,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,同样传入一个该类型的变量地址,

代码示例:

.pro

#-------------------------------------------------
#
# 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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

.h:

#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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

.cpp

#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();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

测试结果:

在这里插入图片描述

over:

欢迎大家关注作者在文末评论、点赞、转发以及批评指正!
如果大家有更好的方法或有问题可以在文末评论一起讨论!
共同学习!
共同进步!

文末一句话:

人这一生会说上万个谎言,最容易脱口而出的那个是:没事,我很好。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/305205
推荐阅读
相关标签
  

闽ICP备14008679号