Qt開發的UDP發送端

    1、準備html

    (一)開發環境windows

    系統:Windows 7 專業版(64位)網絡

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

    注:Qt下載連接http://download.qt.io/official_releases/qt/函數

    (二)知識準備ui

    Qt 5入門請看書籍《C++ Qt5 範例開發大全 》(可經過網絡搜索,也能夠經過Qt交流QQ羣得到)。this

    Qt建立工程請看百度教程:http://jingyan.baidu.com/article/7908e85c95d538af491ad274.html網絡傳輸協議

    網絡傳輸協議知識,請自行腦補!編碼

    2、開發過程spa

    (一)建立Qt 工程,命名udpEndpoint1(任何名字均可以,只要符合Qt文件命名規則)

    建立沒有嚴格按照步驟一步步來,就點一下關鍵的地方。

    1. 選擇QWidget基類

    

    2. 建立完成

    

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

QT       += core gui

    右邊加上「network」,這一步很是重要,這樣才能加載Qt中與網絡有關的庫(這是我本身的理解,不專業),否則後面程序運行會報錯。修改以下:

QT       += core gui network

    注:請注意一下.pro的內容和工程文件中頭文件和源文件下的文件,後文中會用到。

    (三)建立一個新類(類名:udpSender

    建立類的步驟:

    1. 點擊:文件 --> 新建文件或項目,進入界面以下

    

    2. 選擇:文件和類 --> C++

    

    3. 選擇C++ Class,進入界面以下圖

    

    4. 類名:udpSender,基類(Base Class):QObject,類存放路徑必定要保證存在main.c所在的路徑下(以前我建立在其餘路徑,工程文件裏不出現類定義文件:.cpp和.h)

    

    5.一路「下一步」,直到完成

    

    頭文件裏就多了個udpsender.h,源文件裏也多了個udpsender.cpp。再看.pro文件內容,SOURCES下面多了一個udpsender.cpp;HEADERS,下面也多了個udpsender.h

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

HEADERS  += widget.h \
    udpsender.h

    (四)定義類文件

    1.打開udpsender.h,修改代碼爲:

//udpsender.h
#ifndef UDPSENDER_H
#define UDPSENDER_H

#include <QObject>
#include <QtNetwork/QUdpSocket>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QHostInfo>

class udpSender : public QObject
{
    Q_OBJECT
public:
    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,設計以下界面

控件的屬性以下:

控件標記 控件類型 控件名稱(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 <QWidget>
#include <udpsender.h>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    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 <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

(七)運行程序

點擊運行按鈕,運行結果以下:

實例

我要用本機的udp socket的8082口發送數據到另外一臺主機(IP: 10.106.10.203,PORT:8083),發送數據爲:Hello,很高興認識你。

輸入界面以下:

到此爲止,udp發送端的程序開發已經完成,udp接收端將在後續的博客中再談。

此帖重在交流,若有問題,請QQ聯繫:1592017939,水平有限,請多指正!

相關文章
相關標籤/搜索