參考視頻:https://www.bilibili.com/video/BV1XW411x7NU?p=61服務器
說明:UDP是面向無鏈接的,客戶端並不與服務器不創建鏈接,直接向服務器發送數據,服務器端也不從客戶端接收鏈接,只負責調用接收函數,等待客戶端鏈接的到達。app
udp通訊模型以下:socket
(1)服務器端ide
1)建立套接字;函數
2)綁定套接字;測試
3)接收或發送數據;ui
4)關閉鏈接。this
(2)客戶端spa
1)建立套接字;3d
2)接收或發送數據;
3)關閉鏈接。
(1)基本udp測試
功能:建立一個窗口,使用127.0.0.1:8888進行迴環測試,自發自收。
實現步驟:
建立套接字並綁定端口,不指定ip:
1 QUdpSocket *udpsocket = NULL; 2 //建立套接字,指定父對象 3 udpsocket = new QUdpSocket(this); 4 //綁定 5 udpsocket->bind(8888);
送數據:
1 //先獲取對方的ip和端口 2 QString ip = ui->lineEdit_ip->text(); 3 qint16 port = ui->lineEdit_port->text().toInt(); 4 //獲取編輯區內容 5 QString str = ui->textEdit_send->toPlainText(); 6 if (str.isEmpty()) { 7 return; 8 } 9 //給指定的IP發送數據 10 udpsocket->writeDatagram(str.toUtf8(), QHostAddress(ip), port);
接收數據:
1 //當對方成功發送數據過來,會自動觸發readyRead()信號 2 connect(udpsocket, &QUdpSocket::readyRead, 3 [=](){ 4 //讀取對方發送的數據 5 char buf[1024] = {0}; 6 QHostAddress cli_addr; //對方地址 7 quint16 port; //對方端口 8 qint64 len = udpsocket->readDatagram(buf, sizeof(buf), &cli_addr, &port); 9 if (len > 0) { 10 //格式化[192.168.2.2:8888]aaaa 11 QString str = QString("[%1:%2] %3").arg(cli_addr.toString()).arg(port).arg(buf); 12 //給編輯區設置內容 13 ui->textEdit_recv->append(str); 14 } 15 } 16 );
完整代碼以下:
widget.h
1 #ifndef WIDGET_H 2 #define WIDGET_H 3 4 #include <QWidget> 5 #include <QUdpSocket> 6 7 namespace Ui { 8 class Widget; 9 } 10 11 class Widget : public QWidget 12 { 13 Q_OBJECT 14 15 public: 16 explicit Widget(QWidget *parent = 0); 17 ~Widget(); 18 19 private slots: 20 void on_pushButton_send_clicked(); 21 22 void on_pushButton_close_clicked(); 23 24 private: 25 Ui::Widget *ui; 26 QUdpSocket *udpsocket = NULL; 27 }; 28 29 #endif // WIDGET_H
widget.cpp
1 #include "widget.h" 2 #include "ui_widget.h" 3 #include <QHostAddress> 4 5 Widget::Widget(QWidget *parent) : 6 QWidget(parent), 7 ui(new Ui::Widget) 8 { 9 ui->setupUi(this); 10 setWindowTitle("服務器端口爲:8888"); 11 12 //建立套接字,指定父對象 13 udpsocket = new QUdpSocket(this); 14 //綁定 15 udpsocket->bind(8888); 16 //當對方成功發送數據過來,會自動觸發readyRead()信號 17 connect(udpsocket, &QUdpSocket::readyRead, 18 [=](){ 19 //讀取對方發送的數據 20 char buf[1024] = {0}; 21 QHostAddress cli_addr; //對方地址 22 quint16 port; //對方端口 23 qint64 len = udpsocket->readDatagram(buf, sizeof(buf), &cli_addr, &port); 24 if (len > 0) { 25 //格式化[192.168.2.2:8888]aaaa 26 QString str = QString("[%1:%2] %3").arg(cli_addr.toString()).arg(port).arg(buf); 27 //給編輯區設置內容 28 ui->textEdit_recv->append(str); 29 } 30 } 31 ); 32 } 33 34 Widget::~Widget() 35 { 36 delete ui; 37 } 38 39 void Widget::on_pushButton_send_clicked() 40 { 41 //先獲取對方的ip和端口 42 QString ip = ui->lineEdit_ip->text(); 43 qint16 port = ui->lineEdit_port->text().toInt(); 44 //獲取編輯區內容 45 QString str = ui->textEdit_send->toPlainText(); 46 if (str.isEmpty()) { 47 return; 48 } 49 //給指定的IP發送數據 50 udpsocket->writeDatagram(str.toUtf8(), QHostAddress(ip), port); 51 } 52 53 void Widget::on_pushButton_close_clicked() 54 { 55 close(); 56 }
運行測試:
(2)UDP廣播
概念:使用UDP廣播,局域網內的其它UDP用戶所有能夠收到廣播的消息。UDP廣播只能在局域網範圍內使用。
Qt中在使用writeDatagram()函數發送數據的時候,將第二個參數設置爲廣播地址QHostAddress::Broadcast就表示UDP廣播。
(3)UDP組播
當咱們須要發送消息給某些特定用戶,或者只接收某些特定用戶的消息時,能夠使用組播進行實現。
組播地址有:
Qt中註冊加入到組播地址須要使用QUdpSocket類的成員函數joinMulticastGroup()。
更改上面的代碼的bind和加入joinMulticastGroup()函數:
1 //用主播,主要使用ipv4地址 2 udpsocket->bind(QHostAddress::AnyIPv4, 8888); 3 //加入某個組播,組播地址是D類地址 4 udpsocket->joinMulticastGroup(QHostAddress("224.0.0.2"));
測試: