Qt-udp通訊

1  簡介

參考視頻: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)關閉鏈接。

2  測試說明

(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
View Code

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 }
View Code

運行測試:

(2)UDP廣播

概念:使用UDP廣播,局域網內的其它UDP用戶所有能夠收到廣播的消息。UDP廣播只能在局域網範圍內使用。

Qt中在使用writeDatagram()函數發送數據的時候,將第二個參數設置爲廣播地址QHostAddress::Broadcast就表示UDP廣播。

(3)UDP組播

當咱們須要發送消息給某些特定用戶,或者只接收某些特定用戶的消息時,能夠使用組播進行實現。

組播地址有:

  • 224.0.0.0~224.0.0.255爲預留的組播地址(永久組地址),地址224.0.0.0保留不作分配,其它地址供路由協議使用;
  • 224.0.1.0~224.0.1.255是公用組播地址,能夠用於Internet;
  • 224.0.2.0~238.255.255.255爲用戶可用的組播地址(臨時組地址),全網範圍內有效;
  • 239.0.0.0~239.255.255.255爲本地管理組播地址,僅在特定的本地範圍內有效。

Qt中註冊加入到組播地址須要使用QUdpSocket類的成員函數joinMulticastGroup()。

更改上面的代碼的bind和加入joinMulticastGroup()函數:

1     //用主播,主要使用ipv4地址
2     udpsocket->bind(QHostAddress::AnyIPv4, 8888);
3     //加入某個組播,組播地址是D類地址
4     udpsocket->joinMulticastGroup(QHostAddress("224.0.0.2"));

測試:

相關文章
相關標籤/搜索