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,水平有限,請多指正!