0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于RAW API的UDP服务器设计

CHANBAEK 来源:木南创智 作者:尹家军 2022-12-14 14:56 次阅读

前面我们已经完成了LwIP协议栈基于逻辑的基本移植,在这一节我们将以RAW API来实现UDP服务器。

1 UDP****协议简述

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,处于传输层,是IP协议的上层协议。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

UDP报头由4个域组成,其中每个域各占用2个字节,具体如下:源端口号、目标端口号、数据报长度、校验值。其数据结构如下:

UDP协议使用端口号为不同的应用保留其各自的数据传输通道。UDP和TCP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。数据发送一方(可以是客户端或服务器端)将UDP数据包通过源端口发送出去,而数据接收一方则通过目标端口接收数据。有的网络应用只能使用预先为其预留或注册的静态端口;而另外一些网络应用则可以使用未被注册的动态端口。因为UDP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。一般来说,大于49151的端口号都代表动态端口。

数据报的长度是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节。不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。

UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。

2 UDP****服务器设计

前面我们简要的介绍了UDP协议及其数据报,接下来我们将考虑怎么实现基于UDP协议的服务器。

首先,我们来看一看与UDP相关的API函数,并对它们作一个初步的介绍,应为我们需要使用它们来实现我们的应用。函数及说明如下:

了解了这些函数,我们现在考虑其实现过程。对于UDP服务器端来说,实现相对简洁。其实现步骤如下:

首先,生成一个新的UDP控制块。

接着,绑定UDP控制块到任意IP地址及制定端口。

最后,为UDP控制块注册数据处理回调函数,这里需要说明一下,这就是RAW AIP的回调函数。根据你要实现的功能不同复杂程度完全不一样。我们由于要实现一个回环服务器,所以相对简单。只需要将收到的信息,以我们想要的方式发送回客户端就可以了。

为了很好的实现UDP服务器,还有一个问题需要设计好,就是我们前面我们曾提到的端口。我们都知道TCP/IP协议族包括有很多的协议,那通讯究竟是针对哪一个协议发生的呢?所谓两台机器间的通讯,实际上是主机上的应用进程间的通讯,端口号就是为了最终实现主机上应用进程的通讯。我们常见且会在后续使用到的协议端口如下:

为了使用方便我们将这些端口定义为宏,并存储到一个专门的文件中。在这里我们本次实现UDP服务器也需要制定一个端口,其实支持UDP的端口都没问题,但为了方便描述我们制定其为回环显示端口。

3 UDP****服务器实现

我们了解了其实现的基本过程,其实并不复杂。事实上,回调函数的内容才是我们真正需要考虑的东西。我们将其实现分为两个部分:一是UDP服务器的初始化部分;二是UDP服务器功能部分,也就是回调函数所执行的内容。

首先实现UDP服务器的初始化部分。初始化部分定义一个新的UDP控制块,并将其绑定到任意IP地址及指定端口。然后注册数据处理回调函数。

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   /* 生成一个新的UDP控制块 */
 8   upcb = udp_new();
 9   
10   /* 绑定upcb块到任意IP地址及指定端口*/
11   udp_bind(upcb, IP_ADDR_ANY, UDP_ECHO_SERVER_PORT);
12  
13   /* 为upcb指定数据处理回调函数 */
14   udp_recv(upcb,UDPServerCallback,(void *)recv_arg);
15 }

关于为什么要将本地IP绑定到任意IP呢?这是因为UDP服务器收到数据包后,LwIP会先判断其数据包的目的IP和端口是否和本地注册的PCB控制块绑定的本地的IP和本地端口号是否匹配。所以我们绑定PCB控制块本地IP设为IP_ADDR_ANY时,只要收到的数据包的目的IP非广播地址,端口号匹配,那么均认为数据包的目的IP和端口是与本地注册的PCB控制块绑定的本地IP和端口号相匹配的。省去了自己构造本地IP的过程。

初始化完毕后,注册了数据处理回调函数。接下来需要实现回调函数的内容。回调函数主要实现对数据的处理,这取决于自己的需求。在这里我们在接收到UDP客户端数据包后,不对其作什么处理,因为这一数据本来无意义,我们对任何的客户端请求给予固定的回复。

1 /* 定义UDP服务器数据处理回调函数 */
 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 }

对于这个回调函数,它实际是赋给一个函数指针,所以虽然它的内容和名称可以随意,但其格式是有要求的:void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *addr, u16_t port)

4 、结论

至此,我们完成了简单的UDP服务器,在这里我们使用客户端来测试一下这个UDP服务器,测试结果如下:

这里只测试了一个客户端两届服务器的情况,其实连接多个客户端的情况也是没问题的。如下:

佷显然,如果我们希望实现更复杂的UDP服务器,我们只需要将我们想实现的功能做到回调函数中就可以了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8120

    浏览量

    82522
  • API
    API
    +关注

    关注

    2

    文章

    1382

    浏览量

    60992
  • UDP
    UDP
    +关注

    关注

    0

    文章

    311

    浏览量

    33620
  • LwIP
    +关注

    关注

    1

    文章

    82

    浏览量

    26620
  • RAW
    RAW
    +关注

    关注

    0

    文章

    20

    浏览量

    3748
收藏 人收藏

    评论

    相关推荐

    用GPRS的UDP协议跟服务器通信时服务器发送的数据收不到

    求助大神,为什么我现在用GPRS的UDP协议跟服务器通信的时候,发送数据正常,服务器那边也能收到,但是服务器发送的数据我为什么会收不到?急求...
    发表于 04-16 06:36

    lwip udp接收问题

    大家好,我正在使用Raw API处理lwip-udp。我的应用代码是服务器。在固定间隔内长时间执行接收时,我面临以下问题。在从客户端接收连续数据包时,
    发表于 04-14 08:49

    关于UDP服务器机制的问题怎么解决

    嗨,我需要了解更多关于UDP服务器机制。以下是我的问题:1。我可以说UDP服务器每次只能服务一个连接吗?之所以这样说是因为当我使用TCPIP
    发表于 05-05 10:38

    如何使用Socket实现UDP服务器

    本教程介绍了如何利用socket 编程来实现一个 UDP 服务器,与客户端进行通信。
    发表于 03-30 06:36

    LWIP的RAW API UDP通信过程是如何实现的

    LWIP的主要特性有哪些?LWIP的RAW API UDP通信过程是如何实现的?
    发表于 11-01 06:53

    用AT+CIPSERVER=1,80启动服务器时,可以启动UDP服务器吗?

    大家好, 我刚收到新的 esp 板,我发现有了新固件,我无法使用 AT 命令 AT+GMR 启动 UDP 服务器,给我的是: 代码:全选AT version:0.21.0.0 SDK version
    发表于 05-15 07:27

    基于STM32F107的UDP服务器程序

    基于STM32F107的UDP服务器程序
    发表于 03-26 15:44 151次下载

    实例64 UDP服务器模型

    JAVA教程之UDP服务器模型,很好的JAVA的资料,快来学习吧
    发表于 04-11 17:28 2次下载

    介绍RAW API接口及应用

    RAW API
    的头像 发表于 07-05 00:35 7113次阅读

    TCP回响客户端:RAW API接口

    TCP回响客户端例程(RAW API)
    的头像 发表于 07-05 00:31 3618次阅读
    TCP回响客户端:<b class='flag-5'>RAW</b> <b class='flag-5'>API</b>接口

    RAW API 接口的TCP服务器

    RAW Tcp回响服务器
    的头像 发表于 07-05 00:10 3617次阅读
    <b class='flag-5'>RAW</b> <b class='flag-5'>API</b> 接口的TCP<b class='flag-5'>服务器</b>

    基于RAW APIUDP客户端设计

    前一节我们实现了基于RAW APIUDP服务器,在接下来,我们进一步利用RAW API实现
    的头像 发表于 12-14 14:59 819次阅读
    基于<b class='flag-5'>RAW</b> <b class='flag-5'>API</b>的<b class='flag-5'>UDP</b>客户端设计

    基于TCP的Telnet服务器设计

    前面我们已经实现了基于RAW API的TCP服务器和客户端,也在此基础上实现了HTTP应用。接下来我们实现一个基于TCP的Telnet服务器应用。
    的头像 发表于 12-14 15:30 925次阅读
    基于TCP的Telnet<b class='flag-5'>服务器</b>设计

    【EsDA应用】串口转UDP服务器

    如何让自动化领域的串口设备具备联网能力?本文将基于EsDA平台,带你开发一个串口转UDP服务器业务,快速实现串口联网功能。    简介 串口服务器在物联网中的应用十分广泛,数据采集上报、远程
    的头像 发表于 02-22 13:20 441次阅读

    【EsDA应用】串口转UDP服务器

    如何让自动化领域的串口设备具备联网能力?本文将基于EsDA平台,带你开发一个串口转UDP服务器业务,快速实现串口联网功能。简介串口服务器在物联网中的应用十分广泛,数据采集上报、远程控制等网络化项目
    的头像 发表于 03-06 13:55 390次阅读
    【EsDA应用】串口转<b class='flag-5'>UDP</b><b class='flag-5'>服务器</b>