zoukankan      html  css  js  c++  java
  • Qt学习之网络编程(二)

    UDP协议

    UDP协议(用户数据报协议)是一种简单轻量级、不可靠、面向数据报、无连接的传输层协议。之后我们会介绍TCP协议,相对于UDP,TCP是一种可靠的、有连接的协议;既然这样我们就用TCP不就好了?UDP一直沿用至今是有它的必要意义的,什么意义---UDP它快呀。在进行可靠性并不是需要那么搞得情况下,UDP绝对是首选,比如视频聊天就是UDP协议传输的额,所以有时会出现卡顿的情况,但实际上并不影响我们的使用。下面我们来实现它:
    01.png

    UDP Server

    创建界面

    定义好组件

    #ifndef UDPSERVER_H
    #define UDPSERVER_H
    
    #include <QDialog>
    #include <QLabel>
    #include <QLineEdit>
    #include <QPushButton>
    #include <QVBoxLayout>
    
    class UdpServer : public QDialog
    {
        Q_OBJECT
    
    public:
        UdpServer(QWidget *parent = 0,Qt::WindowFlags f=0);
        ~UdpServer();
        
    private:
        QLabel *TimerLabel;
        QLineEdit *TextLineEdit;
        QPushButton *StartButton;
        QVBoxLayout *mainLayout;
    };
    
    #endif // UDPSERVER_H
    

    再在udpserver.cpp文件中将界面具体实现:

    #include "udpserver.h"
    
    UdpServer::UdpServer(QWidget *parent, Qt::WindowFlags f)
        : QDialog(parent, f)
    {
        setWindowTitle(tr("UDP Server"));
        
        TimerLabel = new QLabel(tr("计时器:"),this);
        TextLineEdit = new QLineEdit(this);
        StaratButton = new QPushButton(tr("开始"),this);
        
        mainLayout = new QVBoxLayout(this);
        mainLayout->addWidget(TimerLabel);
        mainLayout->addWidget(TextLineEdit);
        mainLayout->addWidget((StartButton));
    }
    
    UdpServer::~UdpServer()
    {
    
    }
    
    

    与之前的代码中的QWidget不太相同,这里用的是QDialog,而且代码中QWidget(QWidget *parent=0,Qt::WindowFlags f=0)增加了Qt::WindowFlags。我在这先说一说区别,QWidget *parent=0是父窗口部件的指定,后面的新增组件只用利用this指针附着在上面就行了,如果没有this则会被父窗口遮挡。QT::WindowFlags=0是指定控件的窗口标识,值为0(Qt::Widget)。而窗口标识是由窗口类型和窗口提示hint,首先判断一个控件是否是窗体先根据参数parent的指定,要是值为0那么就可以判断其是一个窗口。否则需要根据Qt::WindowFlags枚举类型的值才可以判断其是否为窗口还是部件。由于Qt::WindowFlags为枚举类型,所以会将QWidget、QWindow、QDialog....组件或者窗口进行枚举,表示窗口或者组件的作用。
    实现界面如下图:
    02.png

    功能实现

    首先在udpserver.h中声明public slots,为StartButtonClicked()与timeout()两个方法;之后再在private中声明port、判断是否点击开始了的isStarteddebol变量、一个udp套接字、计时器timer。
    然后我们需要在udpServer.cpp中完成StartButtonClicked()与timeout()两个函数。StartButtonClicked()比较简单,只是一个判断让按钮显示“开始”还是“停止”,并将是否点击开始了的isStarteddebol变量置为相应的参数,同时需要开始一个计时器如果timer->start(1000)即1000s过后就自动断开连接。
    实现timeout(),之前的connect(..,SIGNAL(timeout()),..,SLOT(timeout()))函数是将信息timeout的数据进行绑定;如果输入的信息位空字符串,则直接返回。QHostAddress::Broadcast指定向广播地址发送,这里是向port发送数据。

    UDP Client

    同样是创建界面和功能实现两个部分,创建界面就一笔带过了,这里谈谈功能实现中关于套接字实现的这个地方。功能代码如下:

     port = 5555;
    
        udpSocket = new QUdpSocket(this);
        connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
    
        bool result = udpSocket->bind(port);
    
    

    首先创建一个udp套接字,然后将套接字绑定在端口5555上,这样服务器端和客户端都有一个端口5555,则可以实现通信。而connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));这句中,代表连接QIODevice的readyRead()信号。QUdpSocket也是一个I/O设备,从QIODevice继承而来,当有关数据到达I/O设备的时候,会发出readyRead()信号。
    dataReceived()函数实现代码:

    void UdpClient::dataReceived()
    {
        while(udpSocket->hasPendingDatagrams())
        {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
    
            udpSocket->readDatagram(datagram.data(),datagram.size());
            QString msg=datagram.data();
            ReceiveTextEdit->insertPlainText(msg);
        }
    }
    

    while(udpSocket->hasPendingDatagrams()),这句代码的意思是判断UdpSocket中是否有数据报可读,hasPendingDatagrams()方法在至少有一个数据报可读时返回true,否则返回false.最后一句 ReceiveTextEdit->insertPlainText(msg);的功能是显示代码,中间部分代码是读取第一个数据报。
    最终效果图如下:
    03.png

    04.png

    05.png

    作者:YunLambert

    -------------------------------------------

    个性签名:一名会音乐、爱健身的不合格程序员

    可以Follow博主的Github哦(っ•̀ω•́)っ✎⁾⁾

  • 相关阅读:
    好代码收藏
    JVM
    关于Redis
    记录ok6410 使用ov9650摄像头的过程
    记录一下在uyuv 转 planar yuv420 的做法
    mini2440 使用的mkyaffs2image 工具的源码
    hi3516a imx178 uboot 默认启动参数
    记录ok6410 使用fast150u 无线网卡的过程 其中部分内容为转载 没有修改
    ubuntu建立tftp服务器有两种方式
    转载hi3516 sd 只读解决
  • 原文地址:https://www.cnblogs.com/yunlambert/p/8556830.html
Copyright © 2011-2022 走看看