前言:前一篇講了TCP通信,這篇來看看UDP通信。
這里說明一下,UDP通信中分為三種通信分別為單播、組播和廣播,下面將一一為大家介紹。
同樣的我們都需要在工程文件中添加network
QT += core gui network
進行UDP通信需要用到的頭文件
#include <QUdpSocket>
這里我們把UDP通信分為兩個部分寫,一個是發送端,另一個是接收端,而發送端中又分為單播、組播和廣播三種形式,下面我們先來看看寫發送端的代碼程序的步驟:
發送端Udpsend的代碼:
1、單播
(1)創建套接字
QUdpSocket mSocket;
mSocket = new QUdpSocket();
(2)發送數據到指定的地址和端口號
mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677);
參數:ui->textEdit->toPlainText().toUtf8 要發送的消息
QHostAddress("192.168.137.1") 接收端的ip地址
6677 端口號,要和接收端的一致
2、組播,組播和單播的步驟是一樣的,只有ip地址處有區別
組播ip地址范圍:224.0.0.0-239.255.255.255 例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677);
3、廣播,廣播也只有ip地址和單播有區別
廣播地址ip:QHostAddress::Broadcast
例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,6677);
好了,單播、組播和廣播的區別應該都了解了,那么我們就來看發送端(udpsend.cpp)的具體代碼:
1 #include "udpsend.h" 2 #include "ui_udpsend.h" 3 4 UdpSend:: UdpSend(QWidget *parent) : 5 QMainWindow(parent), 6 ui(new Ui:: UdpSend) 7 { 8 ui->setupUi(this); 9 10 //初始化創建QUdpSocket對象 11 mSocket = new QUdpSocket(); 12 } 13 14 UdpSend::~ UdpSend() 15 { 16 delete ui; 17 } 18 19 void UdpSend::on_sendBt_clicked() 20 { 21 //單播 22 // qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677); 23 24 25 //組播ip地址范圍:224.0.0.0-239.255.255.255 26 //qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677); 27 28 //廣播 29 qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,6677); 30 31 32 }
發送端的界面文件我做的很簡單,我只做了發送消息框:
看完發送端的代碼,我們繼續來看接收端的代碼(Udprecv)
接收端不管是單播、或者組播還是廣播代碼都是一樣的,下面是寫接收端代碼的步驟:
1、創建套接字
QUdpSocket mSocket; mSocket = new QUdpSocket();
2、綁定地址和端口號
mSocket->bind(QHostAddress::AnyIPv4,6677); 參數:AnyIPv4 IPv4 6677 端口號,要和發送端的一致
3、等待數據的到來,利用readyRread()
connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
4、讀數據
readDatagram(char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0) 參數: data:數據 maxSize:數據的大小 address:QHostAddress類型的地址 port:端口號 例子: void UdpRecv::read_data() { QByteArray array; QHostAddress address; quint16 port; array.resize(mSocket->bytesAvailable());//根據可讀數據來設置空間大小 mSocket->readDatagram(array.data(),array.size(),&address,&port); //讀取數據 ui->listWidget->addItem(array);//顯示數據 //發送反饋數據 }
如果是組播的話還涉及到加入組播和退出組播
加入到組播組 joinMulticastGroup 例子:mSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
退出組播組 leaveMulticastGroup 例子: mSocket->leaveMulticastGroup(QHostAddress("224.0.0.100"));
來看看接收端(Udprecv.cpp)具體實現的代碼
1 #include "udprecv.h" 2 #include "ui_udprecv.h" 3 4 UdpRecv::UdpRecv(QWidget *parent) : 5 QMainWindow(parent), 6 ui(new Ui::UdpRecv) 7 { 8 ui->setupUi(this); 9 10 //創建對象 初始化 11 mSocket = new QUdpSocket(); 12 13 //綁定 14 mSocket->bind(QHostAddress::AnyIPv4,6677); 15 //關聯讀數據信號readyread 16 connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data())); 17 18 } 19 20 UdpRecv::~UdpRecv() 21 { 22 delete ui; 23 } 24 25 void UdpRecv::read_data() 26 { 27 QByteArray array; 28 QHostAddress address; 29 quint16 port; 30 array.resize(mSocket->bytesAvailable());//根據可讀數據來設置空間大小 31 mSocket->readDatagram(array.data(),array.size(),&address,&port); //讀取數據 32 ui->listWidget->addItem(array);//顯示數據 33 //發送反饋數據 34 35 } 36 37 void UdpRecv::on_checkBox_clicked(bool checked) 38 { 39 if(checked) 40 { 41 //加入組播 42 mSocket->joinMulticastGroup(QHostAddress("224.0.0.100")); 43 } 44 45 else 46 { 47 //退出組播 48 mSocket->leaveMulticastGroup(QHostAddress("224.0.0.100")); 49 50 } 51 52 }
接收端的界面文件我只加了顯示接收到的信息和選擇是否加入組播的選擇按鈕
這是發送端和接收分開來寫的,此外我也實現了一下發送端和接收端寫到同一個文件中
頭文件qudpapp.h中的代碼

1 #ifndef QUDPAPP_H 2 #define QUDPAPP_H 3 4 #include <QWidget> 5 #include <QUdpSocket> 6 namespace Ui { 7 class QUdpApp; 8 } 9 10 class QUdpApp : public QWidget 11 { 12 Q_OBJECT 13 14 public: 15 explicit QUdpApp(QWidget *parent = 0); 16 ~QUdpApp(); 17 18 private slots: 19 void on_sendSigRb_clicked(); //單播旋轉軸 20 void on_sendMulRb_clicked(); //組播選擇 21 void on_sendBroadRb_clicked(); //廣播選擇 22 void on_sendBt_clicked(); //發送按鈕 23 24 //=========================================== 25 void on_recvCb_clicked(bool checked); //選擇接收 26 void on_recvJoinMulBt_clicked(); //加入組播 27 void on_recvLeaveMulBt_clicked(); //退出組播 28 29 void on_sendMesEdit_cursorPositionChanged();//檢測消息框是否有數據 30 void read_data(); 31 32 private: 33 Ui::QUdpApp *ui; 34 QUdpSocket *mSocket; 35 QHostAddress sendaddrees; 36 QString sendPort; 37 38 }; 39 40 #endif // QUDPAPP_H
源文件qudpapp.cpp中的代碼

1 #include "qudpapp.h" 2 #include "ui_qudpapp.h" 3 #include <QMessageBox> 4 QUdpApp::QUdpApp(QWidget *parent) : 5 QWidget(parent), 6 ui(new Ui::QUdpApp) 7 { 8 ui->setupUi(this); 9 mSocket = new QUdpSocket();//創建套接字 10 ui->sendBt->setEnabled(false); 11 } 12 13 QUdpApp::~QUdpApp() 14 { 15 delete ui; 16 } 17 18 19 //==========================發送端==================== 20 //單播選擇 21 void QUdpApp::on_sendSigRb_clicked() 22 { 23 if(ui->sendPortEdit->text().isEmpty() || ui->sendSigAddrEdit->text().isEmpty()) 24 { 25 QMessageBox::warning(this,"提示","請輸入單播ip和端口號"); 26 //ui->sendSigRb->setChecked(false); 27 return; 28 } 29 sendaddrees.setAddress( ui->sendSigAddrEdit->text()); 30 sendPort = ui->sendPortEdit->text(); 31 32 } 33 34 //組播選擇 35 void QUdpApp::on_sendMulRb_clicked() 36 { 37 if(ui->sendPortEdit->text().isEmpty() || ui->sendMulAddrEdit->text().isEmpty()) 38 { 39 QMessageBox::warning(this,"提示","請輸入組播ip和端口號"); 40 //ui->sendSigRb->setChecked(false); 41 return; 42 } 43 sendaddrees.setAddress( ui->sendMulAddrEdit->text()); 44 sendPort = ui->sendPortEdit->text(); 45 46 } 47 48 //廣播選擇 49 void QUdpApp::on_sendBroadRb_clicked() 50 { 51 if(ui->sendPortEdit->text().isEmpty() || ui->sendBroadAddrEdit->text().isEmpty()) 52 { 53 QMessageBox::warning(this,"提示","請輸入廣播ip和端口號"); 54 //ui->sendSigRb->setChecked(false); 55 return; 56 } 57 sendaddrees.setAddress( ui->sendBroadAddrEdit->text()); 58 sendPort = ui->sendPortEdit->text(); 59 60 } 61 62 //發送按鈕 63 void QUdpApp::on_sendBt_clicked() 64 { 65 mSocket->writeDatagram(ui->sendMesEdit->toPlainText().toUtf8(),sendaddrees,sendPort.toInt()); 66 67 } 68 69 //檢測發送消息對話框中是否有消息 70 void QUdpApp::on_sendMesEdit_cursorPositionChanged() 71 { 72 if(ui->sendMesEdit->toPlainText().isEmpty()) 73 { 74 ui->sendBt->setEnabled(false); 75 } 76 else 77 { 78 ui->sendBt->setEnabled(true); 79 } 80 81 } 82 83 //==========================發送端==================== 84 85 86 //==========================接收端===================== 87 88 //選擇接收 89 void QUdpApp::on_recvCb_clicked(bool checked) 90 { 91 if(ui->recvPortEdit->text().isEmpty()) 92 { 93 QMessageBox::warning(this,"提示","請輸入端口號"); 94 ui->recvCb->setChecked(false); 95 return; 96 } 97 if(checked) 98 { 99 mSocket->bind(QHostAddress::AnyIPv4,ui->recvPortEdit->text().toInt()); 100 connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data())); 101 ui->recvPortEdit->setEnabled(false); 102 } 103 else 104 { 105 mSocket->close(); 106 ui->recvPortEdit->setEnabled(true); 107 } 108 } 109 110 //加入組播 111 void QUdpApp::on_recvJoinMulBt_clicked() 112 { 113 if(ui->recvMulAddrEdit->text().isEmpty()) 114 { 115 QMessageBox::warning(this,"提示","請輸入組播ip"); 116 return; 117 } 118 if(mSocket->joinMulticastGroup(QHostAddress(ui->recvMulAddrEdit->text()))) //加入組播 119 { 120 ui->recvMulAddr->addItem(ui->recvMulAddrEdit->text()); 121 } 122 else 123 { 124 QMessageBox::warning(this,"提示","加入組播失敗,請修改ip后繼續加入"); 125 //return; 126 } 127 128 } 129 130 //退出組播 131 void QUdpApp::on_recvLeaveMulBt_clicked() 132 { 133 mSocket->leaveMulticastGroup(QHostAddress(ui->recvMulAddr->currentIndex()));//退出組播地址列表當前的組播 134 ui->recvMulAddr->removeItem(ui->recvMulAddr->currentIndex()); //刪除組播地址列表中當前的組播地址 135 } 136 137 void QUdpApp::read_data() 138 { 139 QByteArray array; 140 array.resize(mSocket->bytesAvailable()); //將接收數據的array設置成為要接收數據的大小 141 QHostAddress recvaddress; 142 quint16 port; 143 mSocket->readDatagram(array.data(),array.size(),&recvaddress,&port); //讀取數據 144 ui->recvList->addItem(array); 145 146 } 147 148 //==========================接收端=====================
界面文件qudpapp.ui

1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>QUdpApp</class> 4 <widget class="QWidget" name="QUdpApp"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>637</width> 10 <height>561</height> 11 </rect> 12 </property> 13 <property name="sizePolicy"> 14 <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> 15 <horstretch>0</horstretch> 16 <verstretch>0</verstretch> 17 </sizepolicy> 18 </property> 19 <property name="windowTitle"> 20 <string>QUdpApp</string> 21 </property> 22 <widget class="QWidget" name="layoutWidget"> 23 <property name="geometry"> 24 <rect> 25 <x>9</x> 26 <y>9</y> 27 <width>394</width> 28 <height>463</height> 29 </rect> 30 </property> 31 <layout class="QVBoxLayout" name="verticalLayout_6"> 32 <item> 33 <layout class="QHBoxLayout" name="horizontalLayout_9"> 34 <item> 35 <widget class="QGroupBox" name="groupBox"> 36 <property name="sizePolicy"> 37 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 38 <horstretch>0</horstretch> 39 <verstretch>0</verstretch> 40 </sizepolicy> 41 </property> 42 <property name="title"> 43 <string>發送端</string> 44 </property> 45 <layout class="QVBoxLayout" name="verticalLayout_3"> 46 <property name="spacing"> 47 <number>0</number> 48 </property> 49 <property name="leftMargin"> 50 <number>0</number> 51 </property> 52 <property name="topMargin"> 53 <number>0</number> 54 </property> 55 <property name="rightMargin"> 56 <number>0</number> 57 </property> 58 <property name="bottomMargin"> 59 <number>0</number> 60 </property> 61 <item> 62 <layout class="QVBoxLayout" name="verticalLayout_2"> 63 <item> 64 <layout class="QHBoxLayout" name="horizontalLayout"> 65 <property name="spacing"> 66 <number>0</number> 67 </property> 68 <item> 69 <widget class="QLabel" name="label"> 70 <property name="text"> 71 <string>端 口 號</string> 72 </property> 73 </widget> 74 </item> 75 <item> 76 <widget class="QLineEdit" name="sendPortEdit"> 77 <property name="sizePolicy"> 78 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 79 <horstretch>0</horstretch> 80 <verstretch>0</verstretch> 81 </sizepolicy> 82 </property> 83 <property name="placeholderText"> 84 <string>請輸入端口號</string> 85 </property> 86 </widget> 87 </item> 88 </layout> 89 </item> 90 <item> 91 <layout class="QHBoxLayout" name="horizontalLayout_2"> 92 <property name="spacing"> 93 <number>0</number> 94 </property> 95 <item> 96 <widget class="QRadioButton" name="sendSigRb"> 97 <property name="text"> 98 <string>單播</string> 99 </property> 100 </widget> 101 </item> 102 <item> 103 <widget class="QLineEdit" name="sendSigAddrEdit"> 104 <property name="sizePolicy"> 105 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 106 <horstretch>0</horstretch> 107 <verstretch>0</verstretch> 108 </sizepolicy> 109 </property> 110 <property name="placeholderText"> 111 <string>請輸入接收方地址</string> 112 </property> 113 </widget> 114 </item> 115 </layout> 116 </item> 117 <item> 118 <layout class="QHBoxLayout" name="horizontalLayout_3"> 119 <property name="spacing"> 120 <number>0</number> 121 </property> 122 <item> 123 <widget class="QRadioButton" name="sendMulRb"> 124 <property name="text"> 125 <string>組播</string> 126 </property> 127 </widget> 128 </item> 129 <item> 130 <widget class="QLineEdit" name="sendMulAddrEdit"> 131 <property name="sizePolicy"> 132 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 133 <horstretch>0</horstretch> 134 <verstretch>0</verstretch> 135 </sizepolicy> 136 </property> 137 <property name="placeholderText"> 138 <string>請輸入組播地址</string> 139 </property> 140 </widget> 141 </item> 142 </layout> 143 </item> 144 <item> 145 <layout class="QHBoxLayout" name="horizontalLayout_4"> 146 <property name="spacing"> 147 <number>0</number> 148 </property> 149 <item> 150 <widget class="QRadioButton" name="sendBroadRb"> 151 <property name="text"> 152 <string>廣播</string> 153 </property> 154 </widget> 155 </item> 156 <item> 157 <widget class="QLineEdit" name="sendBroadAddrEdit"> 158 <property name="sizePolicy"> 159 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 160 <horstretch>0</horstretch> 161 <verstretch>0</verstretch> 162 </sizepolicy> 163 </property> 164 <property name="placeholderText"> 165 <string>請輸入廣播地址</string> 166 </property> 167 </widget> 168 </item> 169 </layout> 170 </item> 171 </layout> 172 </item> 173 </layout> 174 </widget> 175 </item> 176 <item> 177 <widget class="QGroupBox" name="groupBox_2"> 178 <property name="sizePolicy"> 179 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 180 <horstretch>0</horstretch> 181 <verstretch>0</verstretch> 182 </sizepolicy> 183 </property> 184 <property name="title"> 185 <string>接收端</string> 186 </property> 187 <layout class="QVBoxLayout" name="verticalLayout_4"> 188 <item> 189 <layout class="QVBoxLayout" name="verticalLayout"> 190 <item> 191 <layout class="QHBoxLayout" name="horizontalLayout_7"> 192 <item> 193 <widget class="QCheckBox" name="recvCb"> 194 <property name="text"> 195 <string>接收</string> 196 </property> 197 </widget> 198 </item> 199 <item> 200 <widget class="QLineEdit" name="recvPortEdit"> 201 <property name="placeholderText"> 202 <string>請輸入端口號</string> 203 </property> 204 </widget> 205 </item> 206 </layout> 207 </item> 208 <item> 209 <layout class="QHBoxLayout" name="horizontalLayout_5"> 210 <property name="spacing"> 211 <number>0</number> 212 </property> 213 <item> 214 <widget class="QLineEdit" name="recvMulAddrEdit"> 215 <property name="placeholderText"> 216 <string>輸入要加入的組播地址</string> 217 </property> 218 </widget> 219 </item> 220 <item> 221 <widget class="QPushButton" name="recvJoinMulBt"> 222 <property name="maximumSize"> 223 <size> 224 <width>40</width> 225 <height>16777215</height> 226 </size> 227 </property> 228 <property name="text"> 229 <string>加入</string> 230 </property> 231 </widget> 232 </item> 233 </layout> 234 </item> 235 <item> 236 <layout class="QHBoxLayout" name="horizontalLayout_6"> 237 <item> 238 <widget class="QComboBox" name="recvMulAddr"/> 239 </item> 240 <item> 241 <widget class="QPushButton" name="recvLeaveMulBt"> 242 <property name="maximumSize"> 243 <size> 244 <width>40</width> 245 <height>16777215</height> 246 </size> 247 </property> 248 <property name="text"> 249 <string>退出</string> 250 </property> 251 </widget> 252 </item> 253 </layout> 254 </item> 255 </layout> 256 </item> 257 </layout> 258 </widget> 259 </item> 260 </layout> 261 </item> 262 <item> 263 <layout class="QVBoxLayout" name="verticalLayout_5"> 264 <item> 265 <widget class="QListWidget" name="recvList"/> 266 </item> 267 <item> 268 <widget class="QTextEdit" name="sendMesEdit"> 269 <property name="maximumSize"> 270 <size> 271 <width>16777215</width> 272 <height>100</height> 273 </size> 274 </property> 275 </widget> 276 </item> 277 </layout> 278 </item> 279 <item> 280 <layout class="QHBoxLayout" name="horizontalLayout_8"> 281 <item> 282 <widget class="QPushButton" name="clearRecvListBt"> 283 <property name="text"> 284 <string>清除接收區</string> 285 </property> 286 </widget> 287 </item> 288 <item> 289 <widget class="QPushButton" name="clearsendEditBt"> 290 <property name="text"> 291 <string>清除發送區</string> 292 </property> 293 </widget> 294 </item> 295 <item> 296 <spacer name="horizontalSpacer_2"> 297 <property name="orientation"> 298 <enum>Qt::Horizontal</enum> 299 </property> 300 <property name="sizeHint" stdset="0"> 301 <size> 302 <width>40</width> 303 <height>20</height> 304 </size> 305 </property> 306 </spacer> 307 </item> 308 <item> 309 <widget class="QPushButton" name="sendBt"> 310 <property name="text"> 311 <string>發送</string> 312 </property> 313 </widget> 314 </item> 315 </layout> 316 </item> 317 </layout> 318 </widget> 319 </widget> 320 <layoutdefault spacing="6" margin="11"/> 321 <resources/> 322 <connections> 323 <connection> 324 <sender>clearRecvListBt</sender> 325 <signal>clicked()</signal> 326 <receiver>recvList</receiver> 327 <slot>clear()</slot> 328 <hints> 329 <hint type="sourcelabel"> 330 <x>47</x> 331 <y>448</y> 332 </hint> 333 <hint type="destinationlabel"> 334 <x>70</x> 335 <y>227</y> 336 </hint> 337 </hints> 338 </connection> 339 <connection> 340 <sender>clearsendEditBt</sender> 341 <signal>clicked()</signal> 342 <receiver>sendMesEdit</receiver> 343 <slot>clear()</slot> 344 <hints> 345 <hint type="sourcelabel"> 346 <x>134</x> 347 <y>455</y> 348 </hint> 349 <hint type="destinationlabel"> 350 <x>145</x> 351 <y>410</y> 352 </hint> 353 </hints> 354 </connection> 355 </connections> 356 </ui>
界面文件圖示