天天看點

第十七章 ESP32的UDP廣播

關注嘉友創科技公衆号

第十七章 ESP32的UDP廣播

  • 源碼位址:​​https://github.com/HX-IoT/ESP32-Developer-Guide​​
  • ESP32開發指南QQ群:824870185,内有pdf版,排版整潔。

學習目的及目标

  1. 掌握UDP原理和工作過程
  2. 掌握樂鑫ESP32的UDP的程式設計
  3. 主要掌握UDP源碼過程

UDP科普(來自百度百科)

UDP 是User Datagram Protocol的簡稱, 中文名是使用者資料報協定,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連接配接的傳輸層協定,提供面向事務的簡單不可靠資訊傳送服務,IETF RFC 768是UDP的正式規範。UDP在IP封包的協定号是17。

UDP協定全稱是使用者資料報協定,在網絡中它與TCP協定一樣用于處理資料包,是一種無連接配接的協定。在OSI模型中,在第四層——傳輸層,處于IP協定的上一層。UDP有不提供資料包分組、組裝和不能對資料包進行排序的缺點,也就是說,當封包發送之後,是無法得知其是否安全完整到達的。UDP用來支援那些需要在計算機之間傳輸資料的網絡應用。包括網絡視訊會議系統在内的衆多的客戶/伺服器模式的網絡應用都需要使用UDP協定。UDP協定從問世至今已經被使用了很多年,雖然其最初的光彩已經被一些類似協定所掩蓋,但是即使是在今天UDP仍然不失為一項非常實用和可行的網絡傳輸層協定。

與所熟知的TCP(傳輸控制協定)協定一樣,UDP協定直接位于IP(網際協定)協定的頂層。根據OSI(開放系統互連)參考模型,UDP和TCP都屬于傳輸層協定。UDP協定的主要作用是将網絡資料流量壓縮成資料包的形式。一個典型的資料包就是一個二進制資料的傳輸機關。每一個資料包的前8個位元組用來包含報頭資訊,剩餘位元組則用來包含具體的傳輸資料。

UDP是OSI參考模型中一種無連接配接的傳輸層協定,它主要用于不要求分組順序到達的傳輸中,分組傳輸順序的檢查與排序由應用層完成,提供面向事務的簡單不可靠資訊傳送服務。UDP 協定基本上是IP協定與上層協定的接口。UDP協定适用端口分别運作在同一台裝置上的多個應用程式。

UDP提供了無連接配接通信,且不對傳送資料包進行可靠性保證,适合于一次傳輸少量資料,UDP傳輸的可靠性由應用層負責。常用的UDP端口号有:

應用協定 端口号
DNS 53
TFTP 69
SNMP 161

UDP封包沒有可靠性保證、順序保證和流量控制字段等,可靠性較差。但是正因為UDP協定的控制選項較少,在資料傳輸過程中延遲小、資料傳輸效率高,适合對可靠性要求不高的應用程式,或者可以保障可靠性的應用程式,如DNS、TFTP、SNMP等。

UDP特點和流程

上面的原理很重要,但畢竟我們隻是在API之上做應用。隻需要了解特點和流程。知道特點可以做方案時候考量可行性,流程就是可行後的實施。

UDP特點:

  1. 無連接配接的:發資料前不需要建立連接配接。
  2. 不可靠:盡最大努力傳遞,即不保證可靠傳遞。
  3. 支援一對一,一對多,多對一和多對多的互動通信
  4. 占用資源少,發送資料快。

UDP流程: (本段來源)

UDP程式設計的用戶端一般步驟是:

  1. 1.建立 UDP socket套接字,用socket()函數。
  2. 2.用sendto()函數往指定的IP,位址發送資訊。

TCP程式設計的伺服器端一般步驟是: 

  1. 建立 UDP socket套接字,用socket函數。
  2. 設定socket的屬性,用setsockopt()函數,(可選)
  3. 綁定包含 IP資訊,位址資訊的(IPv4)結構體。用bind()函數
  4. 循環接收消息,用recvfrom()函數
  5. 關閉socket套接字

TCP團夥和UDP團夥

第十七章 ESP32的UDP廣播

軟體設計

ESP32的UDP詳細過程

第十七章 ESP32的UDP廣播

ESP32的UDP Client接口介紹

連接配接函數:connect();

關閉socket函數:close();

擷取socket錯誤代碼:getsocketopt();

接收資料函數:recvfrom();

發送資料函數:sendto();

更多更詳細接口請參考​​官方指南​​。

ESP32的UDP總結

初始化wifi配置後,程式會根據WIFI的實時狀态,在回調函數中給出狀态傳回,是以隻需要在回調中進行相關操作,STA開始事件觸發UDP工作,上後就可以進行資料的廣播。

UDP建立任務編寫

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

esp_err_t create_udp_client()

{

    ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d",

             UDP_ADRESS, UDP_PORT);

    //建立socket

    connect_socket = socket(AF_INET, SOCK_DGRAM, 0);                         /*參數和TCP不同*/

    if (connect_socket < 0)

    {

        //列印報錯資訊

        show_socket_error_reason("create client", connect_socket);

        //建立失敗後,關閉建立的socket,等待下次建立

        close(connect_socket);

        return ESP_FAIL;

    }

    //配置連接配接伺服器資訊

    client_addr.sin_family = AF_INET;

    client_addr.sin_port = htons(UDP_PORT);

    client_addr.sin_addr.s_addr = inet_addr(UDP_ADRESS);

    int len = 0;            //長度

    char databuff[1024] = "Hello Server,Please ack!!";    //緩存

    //測試udp server,傳回發送成功的長度

len = sendto(connect_socket, databuff, 1024, 0, (struct sockaddr *) &client_addr,

sizeof(client_addr));

if (len > 0) {

ESP_LOGI(TAG, "Transfer data to %s:%u,ssucceed\n",

inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

} else {

        show_socket_error_reason("recv_data", connect_socket);

close(connect_socket);

return ESP_FAIL;

}

    return ESP_OK;

UDP接收任務代碼

void recv_data(void *pvParameters)

    char databuff[1024];    //緩存

    while (1)

        //清空緩存

        memset(databuff, 0x00, sizeof(databuff));

        //讀取接收資料

len = recvfrom(connect_socket, databuff, sizeof(databuff), 0,

(struct sockaddr *) &client_addr, &socklen);

        if (len > 0)

        {

            //列印接收到的數組

            ESP_LOGI(TAG, "UDP Client recvData: %s", databuff);

            //接收資料回發

            sendto(connect_socket, databuff, strlen(databuff), 0,

            (struct sockaddr *) &client_addr, sizeof(client_addr));

        }

        else

            //列印錯誤資訊

            show_socket_error_reason("UDP Client recv_data", connect_socket);

            break;

    close_socket();

    vTaskDelete(NULL);

測試流程和效果展示

測試流程

修改AP和STA的賬号密碼

修改UDP Port

使用手機或者電腦使用助手工具進行UDP廣播測試

效果展示

測試發送資料

第十七章 ESP32的UDP廣播

收發小測

第十七章 ESP32的UDP廣播

發送100次,看看不可靠的程度

第十七章 ESP32的UDP廣播

UDP總結

底層重原理,應用中流程+接口。

此源碼沒有異常處理,自己移植需要适當修改,在接收任務中看傳回值,決定是否重新建立UDP Client,與TCP類似的操作。