0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于RAW API的UDP服務(wù)器設(shè)計(jì)

CHANBAEK ? 來(lái)源:木南創(chuàng)智 ? 作者:尹家軍 ? 2022-12-14 14:56 ? 次閱讀

前面我們已經(jīng)完成了LwIP協(xié)議棧基于邏輯的基本移植,在這一節(jié)我們將以RAW API來(lái)實(shí)現(xiàn)UDP服務(wù)器。

1 、 UDP****協(xié)議簡(jiǎn)述

UDP協(xié)議全稱是用戶數(shù)據(jù)報(bào)協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無(wú)連接的協(xié)議。在OSI模型中,處于傳輸層,是IP協(xié)議的上層協(xié)議。UDP有不提供數(shù)據(jù)包分組、組裝和不能對(duì)數(shù)據(jù)包進(jìn)行排序的缺點(diǎn),也就是說(shuō),當(dāng)報(bào)文發(fā)送之后,是無(wú)法得知其是否安全完整到達(dá)的。

UDP協(xié)議的主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流量壓縮成數(shù)據(jù)包的形式。一個(gè)典型的數(shù)據(jù)包就是一個(gè)二進(jìn)制數(shù)據(jù)的傳輸單位。每一個(gè)數(shù)據(jù)包的前8個(gè)字節(jié)用來(lái)包含報(bào)頭信息,剩余字節(jié)則用來(lái)包含具體的傳輸數(shù)據(jù)。

UDP報(bào)頭由4個(gè)域組成,其中每個(gè)域各占用2個(gè)字節(jié),具體如下:源端口號(hào)、目標(biāo)端口號(hào)、數(shù)據(jù)報(bào)長(zhǎng)度、校驗(yàn)值。其數(shù)據(jù)結(jié)構(gòu)如下:

UDP協(xié)議使用端口號(hào)為不同的應(yīng)用保留其各自的數(shù)據(jù)傳輸通道。UDP和TCP協(xié)議正是采用這一機(jī)制實(shí)現(xiàn)對(duì)同一時(shí)刻內(nèi)多項(xiàng)應(yīng)用同時(shí)發(fā)送和接收數(shù)據(jù)的支持。數(shù)據(jù)發(fā)送一方(可以是客戶端或服務(wù)器端)將UDP數(shù)據(jù)包通過(guò)源端口發(fā)送出去,而數(shù)據(jù)接收一方則通過(guò)目標(biāo)端口接收數(shù)據(jù)。有的網(wǎng)絡(luò)應(yīng)用只能使用預(yù)先為其預(yù)留或注冊(cè)的靜態(tài)端口;而另外一些網(wǎng)絡(luò)應(yīng)用則可以使用未被注冊(cè)的動(dòng)態(tài)端口。因?yàn)閁DP報(bào)頭使用兩個(gè)字節(jié)存放端口號(hào),所以端口號(hào)的有效范圍是從0到65535。一般來(lái)說(shuō),大于49151的端口號(hào)都代表動(dòng)態(tài)端口。

數(shù)據(jù)報(bào)的長(zhǎng)度是指包括報(bào)頭和數(shù)據(jù)部分在內(nèi)的總字節(jié)數(shù)。因?yàn)閳?bào)頭的長(zhǎng)度是固定的,所以該域主要被用來(lái)計(jì)算可變長(zhǎng)度的數(shù)據(jù)部分。數(shù)據(jù)報(bào)的最大長(zhǎng)度根據(jù)操作環(huán)境的不同而各異。從理論上說(shuō),包含報(bào)頭在內(nèi)的數(shù)據(jù)報(bào)的最大長(zhǎng)度為65535字節(jié)。不過(guò),一些實(shí)際應(yīng)用往往會(huì)限制數(shù)據(jù)報(bào)的大小,有時(shí)會(huì)降低到8192字節(jié)。

UDP協(xié)議使用報(bào)頭中的校驗(yàn)值來(lái)保證數(shù)據(jù)的安全。校驗(yàn)值首先在數(shù)據(jù)發(fā)送方通過(guò)特殊的算法計(jì)算得出,在傳遞到接收方之后,還需要再重新計(jì)算。如果某個(gè)數(shù)據(jù)報(bào)在傳輸過(guò)程中被第三方篡改或者由于線路噪音等原因受到損壞,發(fā)送和接收方的校驗(yàn)計(jì)算值將不會(huì)相符,由此UDP協(xié)議可以檢測(cè)是否出錯(cuò)。

2 、 UDP****服務(wù)器設(shè)計(jì)

前面我們簡(jiǎn)要的介紹了UDP協(xié)議及其數(shù)據(jù)報(bào),接下來(lái)我們將考慮怎么實(shí)現(xiàn)基于UDP協(xié)議的服務(wù)器。

首先,我們來(lái)看一看與UDP相關(guān)的API函數(shù),并對(duì)它們作一個(gè)初步的介紹,應(yīng)為我們需要使用它們來(lái)實(shí)現(xiàn)我們的應(yīng)用。函數(shù)及說(shuō)明如下:

了解了這些函數(shù),我們現(xiàn)在考慮其實(shí)現(xiàn)過(guò)程。對(duì)于UDP服務(wù)器端來(lái)說(shuō),實(shí)現(xiàn)相對(duì)簡(jiǎn)潔。其實(shí)現(xiàn)步驟如下:

首先,生成一個(gè)新的UDP控制塊。

接著,綁定UDP控制塊到任意IP地址及制定端口。

最后,為UDP控制塊注冊(cè)數(shù)據(jù)處理回調(diào)函數(shù),這里需要說(shuō)明一下,這就是RAW AIP的回調(diào)函數(shù)。根據(jù)你要實(shí)現(xiàn)的功能不同復(fù)雜程度完全不一樣。我們由于要實(shí)現(xiàn)一個(gè)回環(huán)服務(wù)器,所以相對(duì)簡(jiǎn)單。只需要將收到的信息,以我們想要的方式發(fā)送回客戶端就可以了。

為了很好的實(shí)現(xiàn)UDP服務(wù)器,還有一個(gè)問(wèn)題需要設(shè)計(jì)好,就是我們前面我們?cè)岬降亩丝?。我們都知道TCP/IP協(xié)議族包括有很多的協(xié)議,那通訊究竟是針對(duì)哪一個(gè)協(xié)議發(fā)生的呢?所謂兩臺(tái)機(jī)器間的通訊,實(shí)際上是主機(jī)上的應(yīng)用進(jìn)程間的通訊,端口號(hào)就是為了最終實(shí)現(xiàn)主機(jī)上應(yīng)用進(jìn)程的通訊。我們常見且會(huì)在后續(xù)使用到的協(xié)議端口如下:

為了使用方便我們將這些端口定義為宏,并存儲(chǔ)到一個(gè)專門的文件中。在這里我們本次實(shí)現(xiàn)UDP服務(wù)器也需要制定一個(gè)端口,其實(shí)支持UDP的端口都沒(méi)問(wèn)題,但為了方便描述我們制定其為回環(huán)顯示端口。

3 、 UDP****服務(wù)器實(shí)現(xiàn)

我們了解了其實(shí)現(xiàn)的基本過(guò)程,其實(shí)并不復(fù)雜。事實(shí)上,回調(diào)函數(shù)的內(nèi)容才是我們真正需要考慮的東西。我們將其實(shí)現(xiàn)分為兩個(gè)部分:一是UDP服務(wù)器的初始化部分;二是UDP服務(wù)器功能部分,也就是回調(diào)函數(shù)所執(zhí)行的內(nèi)容。

首先實(shí)現(xiàn)UDP服務(wù)器的初始化部分。初始化部分定義一個(gè)新的UDP控制塊,并將其綁定到任意IP地址及指定端口。然后注冊(cè)數(shù)據(jù)處理回調(diào)函數(shù)。

1 /* UDP初始化配置 */
 2 void UDP_Server_Initialization(void)
 3 {
 4   static char * recv_arg="We recieved a UDP data
";
 5   struct udp_pcb *upcb;
 6  
 7   /* 生成一個(gè)新的UDP控制塊 */
 8   upcb = udp_new();
 9   
10   /* 綁定upcb塊到任意IP地址及指定端口*/
11   udp_bind(upcb, IP_ADDR_ANY, UDP_ECHO_SERVER_PORT);
12  
13   /* 為upcb指定數(shù)據(jù)處理回調(diào)函數(shù) */
14   udp_recv(upcb,UDPServerCallback,(void *)recv_arg);
15 }

關(guān)于為什么要將本地IP綁定到任意IP呢?這是因?yàn)閁DP服務(wù)器收到數(shù)據(jù)包后,LwIP會(huì)先判斷其數(shù)據(jù)包的目的IP和端口是否和本地注冊(cè)的PCB控制塊綁定的本地的IP和本地端口號(hào)是否匹配。所以我們綁定PCB控制塊本地IP設(shè)為IP_ADDR_ANY時(shí),只要收到的數(shù)據(jù)包的目的IP非廣播地址,端口號(hào)匹配,那么均認(rèn)為數(shù)據(jù)包的目的IP和端口是與本地注冊(cè)的PCB控制塊綁定的本地IP和端口號(hào)相匹配的。省去了自己構(gòu)造本地IP的過(guò)程。

初始化完畢后,注冊(cè)了數(shù)據(jù)處理回調(diào)函數(shù)。接下來(lái)需要實(shí)現(xiàn)回調(diào)函數(shù)的內(nèi)容。回調(diào)函數(shù)主要實(shí)現(xiàn)對(duì)數(shù)據(jù)的處理,這取決于自己的需求。在這里我們?cè)诮邮盏経DP客戶端數(shù)據(jù)包后,不對(duì)其作什么處理,因?yàn)檫@一數(shù)據(jù)本來(lái)無(wú)意義,我們對(duì)任何的客戶端請(qǐng)求給予固定的回復(fù)。

1 /* 定義UDP服務(wù)器數(shù)據(jù)處理回調(diào)函數(shù) */
 2 static void UDPServerCallback(void *arg,struct udp_pcb *upcb,struct pbuf *revBuf,const ip_addr_t *addr,u16_t port)
 3 {
 4   struct pbuf *sendBuf = NULL;
 5   const char* reply = "This is reply!
";
 6  
 7   pbuf_free(revBuf);
 8   
 9   sendBuf = pbuf_alloc(PBUF_TRANSPORT, strlen(reply)+1, PBUF_RAM);
10   if(!sendBuf)
11   {
12     return;
13   }
14  
15   memset(sendBuf->payload,0,sendBuf->len);
16   memcpy(sendBuf->payload, reply, strlen(reply));
17   udp_sendto(upcb, sendBuf, addr, port);
18   pbuf_free(sendBuf);
19 }

對(duì)于這個(gè)回調(diào)函數(shù),它實(shí)際是賦給一個(gè)函數(shù)指針,所以雖然它的內(nèi)容和名稱可以隨意,但其格式是有要求的:void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *addr, u16_t port)

4 、結(jié)論

至此,我們完成了簡(jiǎn)單的UDP服務(wù)器,在這里我們使用客戶端來(lái)測(cè)試一下這個(gè)UDP服務(wù)器,測(cè)試結(jié)果如下:

這里只測(cè)試了一個(gè)客戶端兩屆服務(wù)器的情況,其實(shí)連接多個(gè)客戶端的情況也是沒(méi)問(wèn)題的。如下:

佷顯然,如果我們希望實(shí)現(xiàn)更復(fù)雜的UDP服務(wù)器,我們只需要將我們想實(shí)現(xiàn)的功能做到回調(diào)函數(shù)中就可以了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    9160

    瀏覽量

    85415
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1500

    瀏覽量

    62011
  • UDP
    UDP
    +關(guān)注

    關(guān)注

    0

    文章

    325

    瀏覽量

    33937
  • LwIP
    +關(guān)注

    關(guān)注

    2

    文章

    86

    瀏覽量

    27168
  • RAW
    RAW
    +關(guān)注

    關(guān)注

    0

    文章

    21

    瀏覽量

    3801
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何打開UDP服務(wù)器?

    4、封閉式 Where the answer packet should be: (\"RA151[s11=+21.5]+[s12=+20.2]+[s13=+20.3]45\") 有人可以告訴我如何打開UDP服務(wù)器嗎?或者我必須做些什么才能獲得
    發(fā)表于 07-15 07:22

    用GPRS的UDP協(xié)議跟服務(wù)器通信時(shí)服務(wù)器發(fā)送的數(shù)據(jù)收不到

    求助大神,為什么我現(xiàn)在用GPRS的UDP協(xié)議跟服務(wù)器通信的時(shí)候,發(fā)送數(shù)據(jù)正常,服務(wù)器那邊也能收到,但是服務(wù)器發(fā)送的數(shù)據(jù)我為什么會(huì)收不到?急求...
    發(fā)表于 04-16 06:36

    關(guān)于UDP服務(wù)器機(jī)制的問(wèn)題怎么解決

    嗨,我需要了解更多關(guān)于UDP服務(wù)器機(jī)制。以下是我的問(wèn)題:1。我可以說(shuō)UDP服務(wù)器每次只能服務(wù)一個(gè)連接嗎?之所以這樣說(shuō)是因?yàn)楫?dāng)我使用TCPIP
    發(fā)表于 05-05 10:38

    LWIP的RAW API UDP通信過(guò)程是如何實(shí)現(xiàn)的

    LWIP的主要特性有哪些?LWIP的RAW API UDP通信過(guò)程是如何實(shí)現(xiàn)的?
    發(fā)表于 11-01 06:53

    用AT+CIPSERVER=1,80啟動(dòng)服務(wù)器時(shí),可以啟動(dòng)UDP服務(wù)器嗎?

    大家好, 我剛收到新的 esp 板,我發(fā)現(xiàn)有了新固件,我無(wú)法使用 AT 命令 AT+GMR 啟動(dòng) UDP 服務(wù)器,給我的是: 代碼:全選AT version:0.21.0.0 SDK version
    發(fā)表于 05-15 07:27

    基于STM32F107的UDP服務(wù)器程序

    基于STM32F107的UDP服務(wù)器程序
    發(fā)表于 03-26 15:44 ?151次下載

    實(shí)例64 UDP服務(wù)器模型

    JAVA教程之UDP服務(wù)器模型,很好的JAVA的資料,快來(lái)學(xué)習(xí)吧
    發(fā)表于 04-11 17:28 ?2次下載

    介紹RAW API接口及應(yīng)用

    RAW API
    的頭像 發(fā)表于 07-05 00:35 ?7505次閱讀

    RAW API 接口的TCP服務(wù)器

    RAW Tcp回響服務(wù)器
    的頭像 發(fā)表于 07-05 00:10 ?3842次閱讀
    <b class='flag-5'>RAW</b> <b class='flag-5'>API</b> 接口的TCP<b class='flag-5'>服務(wù)器</b>

    基于RAW APIUDP客戶端設(shè)計(jì)

    前一節(jié)我們實(shí)現(xiàn)了基于RAW APIUDP服務(wù)器,在接下來(lái),我們進(jìn)一步利用RAW API實(shí)現(xiàn)
    的頭像 發(fā)表于 12-14 14:59 ?1283次閱讀
    基于<b class='flag-5'>RAW</b> <b class='flag-5'>API</b>的<b class='flag-5'>UDP</b>客戶端設(shè)計(jì)

    基于TCP的Telnet服務(wù)器設(shè)計(jì)

    前面我們已經(jīng)實(shí)現(xiàn)了基于RAW API的TCP服務(wù)器和客戶端,也在此基礎(chǔ)上實(shí)現(xiàn)了HTTP應(yīng)用。接下來(lái)我們實(shí)現(xiàn)一個(gè)基于TCP的Telnet服務(wù)器應(yīng)用。
    的頭像 發(fā)表于 12-14 15:30 ?1357次閱讀
    基于TCP的Telnet<b class='flag-5'>服務(wù)器</b>設(shè)計(jì)

    【EsDA應(yīng)用】串口轉(zhuǎn)UDP服務(wù)器

    如何讓自動(dòng)化領(lǐng)域的串口設(shè)備具備聯(lián)網(wǎng)能力?本文將基于EsDA平臺(tái),帶你開發(fā)一個(gè)串口轉(zhuǎn)UDP服務(wù)器業(yè)務(wù),快速實(shí)現(xiàn)串口聯(lián)網(wǎng)功能。 ?? 簡(jiǎn)介 串口服務(wù)器在物聯(lián)網(wǎng)中的應(yīng)用十分廣泛,數(shù)據(jù)采集上報(bào)、遠(yuǎn)程控制等
    的頭像 發(fā)表于 02-22 13:20 ?703次閱讀

    【EsDA應(yīng)用】串口轉(zhuǎn)UDP服務(wù)器

    如何讓自動(dòng)化領(lǐng)域的串口設(shè)備具備聯(lián)網(wǎng)能力?本文將基于EsDA平臺(tái),帶你開發(fā)一個(gè)串口轉(zhuǎn)UDP服務(wù)器業(yè)務(wù),快速實(shí)現(xiàn)串口聯(lián)網(wǎng)功能。簡(jiǎn)介串口服務(wù)器在物聯(lián)網(wǎng)中的應(yīng)用十分廣泛,數(shù)據(jù)采集上報(bào)、遠(yuǎn)程控制等網(wǎng)絡(luò)化項(xiàng)目都
    的頭像 發(fā)表于 03-06 13:55 ?627次閱讀
    【EsDA應(yīng)用】串口轉(zhuǎn)<b class='flag-5'>UDP</b><b class='flag-5'>服務(wù)器</b>

    【EsDA應(yīng)用】串口服務(wù)器——UDP Server

    如何讓自動(dòng)化領(lǐng)域的串口設(shè)備具備聯(lián)網(wǎng)能力?本文將基于EsDA平臺(tái),帶你開發(fā)一個(gè)串口服務(wù)器UDP服務(wù)器的業(yè)務(wù),快速實(shí)現(xiàn)串口聯(lián)網(wǎng)功能。? ?? 簡(jiǎn)介 串口服務(wù)器本質(zhì)是將串口數(shù)據(jù)通過(guò)各種網(wǎng)絡(luò)
    的頭像 發(fā)表于 07-12 11:45 ?1151次閱讀
    【EsDA應(yīng)用】串口<b class='flag-5'>服務(wù)器</b>——<b class='flag-5'>UDP</b> Server

    服務(wù)器數(shù)據(jù)恢復(fù)—KVM虛擬機(jī)raw格式磁盤文件數(shù)據(jù)恢復(fù)案例

    服務(wù)器數(shù)據(jù)恢復(fù)環(huán)境: 一臺(tái)服務(wù)器安裝Linux操作系統(tǒng)+EXT4文件系統(tǒng)。服務(wù)器上運(yùn)行數(shù)臺(tái)KVM虛擬機(jī),每臺(tái)虛擬機(jī)包含一個(gè)qcow2格式的磁盤文件和一個(gè)raw格式的磁盤文件。
    的頭像 發(fā)表于 05-17 13:33 ?445次閱讀
    <b class='flag-5'>服務(wù)器</b>數(shù)據(jù)恢復(fù)—KVM虛擬機(jī)<b class='flag-5'>raw</b>格式磁盤文件數(shù)據(jù)恢復(fù)案例