LwIP应用开发笔记之三:LwIP无操作系统UDP客户端

前一节我们实现了基于RAW API的UDP服务器,在接下来,我们进一步利用RAW API实现UDP客户端。

1UDP协议简述

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

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

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

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

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

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

2UDP客户端设计

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

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

我们已经了解了UDP服务器的实现步骤,接下来我们说明一下UDP客户端的实现步骤。

首先,依然是创建一个新的UDP控制块。

接下来,建立与服务器的连接,配置包括服务器的地址、端口等信息。

接下来,如果连接无问题,则注册客户端回调函数。与服务器端的实现一样,其复杂程度与需要实现的功能相关。我们只是实现一个简单UDP客户端,所以我们向服务器发送固定的信息,收到回复后继续发送对应的信息。

最后,由于客户端是对话的发起方,所以在注册完回调函数后,客户端要发起首次对话。

3UDP客户端实现

对UDP服务器端的实现,我们依然将器分为两方面内容:一是,UDP客户端的初始化配置部分;二是,UDP客户端的具体实现内容,也就是回调函数的内容。

首先实现UDP客户端的初始化配置部分。定义新的UDP控制块,连接到指定服务器的地址及端口,同样由于我们的验证比较简单我们采用回环服务器端口。然后注册回调函数,发起客户端首次通讯。具体代码如下:

/* UDP客户端初始化配置 */
void UDP_Client_Initialization(void)
{ip_addr_t DestIPaddr;err_t err;struct udp_pcb *upcb;char data[]="This is a Client.";/* 设置服务器端的IP地址 */IP4_ADDR( &DestIPaddr,udpServerIP[0],udpServerIP[1],udpServerIP[2],udpServerIP[3]);/* 创建一个新的UDP控制块 */upcb = udp_new();if (upcb!=NULL){/* 服务器端地址、端口配置 */err= udp_connect(upcb, &DestIPaddr, UDP_ECHO_SERVER_PORT);if (err == ERR_OK){/* 注册回调函数 */udp_recv(upcb, UDPClientCallback, NULL);/**数据发送,第一次连接时客户端发送数据至服务器端,发送函数中会遍历查找源IP地址的配置,如果源IP地址未配置,则数据发送失败。该处出现的问题在后面总结中提到了**/UdpClientSendPacket(upcb,data);}}
}

其次实现UDP客户端的具体实现内容。由于我们实现的简单的响应客户端,所以我们只是给服务器回复相同的内容。

/* 定义UDP客户端数据处理回调函数 */
static void UDPClientCallback(void *arg,struct udp_pcb *upcb,struct pbuf *p,const ip_addr_t *addr,u16_t port)
{udp_send(upcb, p);     //数据回显pbuf_free(p);
}
/* 客户端数据发送函数 */
void UdpClientSendPacket(struct udp_pcb *upcb,char* data)
{struct pbuf *p;/* 分配内存空间 */p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)data), PBUF_POOL);if (p != NULL){/* 复制数据到pbuf */pbuf_take(p, (char*)data, strlen((char*)data));/* 发送数据 */udp_send(upcb, p);     //发送数据/* 释放pbuf */pbuf_free(p);}
}

当然,如果我们不想人云亦云的回复服务器,则可以编辑我们自己的数据包然后发送回去。所以我们想要实现复杂的应用时,只需要重新编写合适的回调函数就可以了!

4、结论

我们完成了简单的,基于RAW API的UDP客户端,其本身并不复杂。同样的我们使用网络软件测试其功能,我们在电脑上建立一个服务器端,然后通过我们这个客户端去连接它。能够进行连接并发送接受数据,说明我们这个客户端的设计是符合要求的。

至此我们完成了UDP客户端及服务器的实现,后续我们将在次基础上实现更为复杂的应用。

欢迎关注:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LwIP应用开发笔记之四:LwIP无操作系统TFTP服务器

前面我们已经实现了UDP的回环客户端和回环服务器的简单应用,接下来我们实现一个基于UDP的简单文件传输协议TFTP。 1、TFTP协议简介 TFTP是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端…

LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器。接下来我们将实现同样广泛应用的TCP协议各类应用。 1、TCP简述 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由…

LwIP应用开发笔记之六:LwIP无操作系统TCP客户端

上一篇我们基于LwIP协议栈的RAW API实现了一个TCP服务器的简单应用,接下来一节我们来实现一个TCP客户端的简单应用。 1、TCP简述 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议&a…

LwIP应用开发笔记之七:LwIP无操作系统HTTP服务器

前面我们实现了TCP服务器和客户端的简单应用,接下来我们实现一个基于TCP协议的应用协议,那就是HTTP超文本传输协议。 1、HTTP协议简介 超文本传输协议(Hyper Text Transfer Protocol),简称HTTP,是一种基于…

LwIP应用开发笔记之八:LwIP无操作系统HTTP客户端

前面我们实现了TCP服务器和客户端的简单应用,接下来我们实现一个基于TCP协议的应用协议,那就是HTTP超文本传输协议 1、HTTP协议简介 超文本传输协议(Hyper Text Transfer Protocol),简称HTTP,是一种基于T…

LwIP应用开发笔记之九:LwIP无操作系统TELNET服务器

前面我们已经实现了基于RAW API的TCP服务器和客户端,也在此基础上实现了HTTP应用。接下来我们实现一个基于TCP的Telnet服务器应用。 1、Telnet协议简介 Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了…

在ARM Cortex-M上实现FreeRTOS性能计数器

说明:本文翻译自Erich Styger的文章《Implementing FreeRTOS Performance Counters on ARM Cortex-M》,文章的权属属于原作者。 当使用像FreeRTOS这样的RTOS时,迟早要问一个问题:每个任务花费多少时间?基于Eclipse的M…

STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出

脉冲信号用于设备控制是非常常见的,但在一些情况下,我们希望精确的控制脉冲的数量以实现对运动的精确控制。实现的方式也许有多种多样,但使用计时器来实现此类操作是人们比较容易想到的。 1、原理概述 我们知道在STM32平台上,使…

外设驱动库开发笔记0:EPD总体设计

在产品开发过程中,不可避免需要使用很多外部的元件及传感器,这些元器件也许是板载的,也许是板外的,但不管怎样,为其开发驱动程序都是必须的。每次都需要为这些元器件编写驱动程序。但每次重复编写调试很麻烦&#xff0…

外设驱动库开发笔记1:AD56xx系列DAC驱动

DAC在我们的项目中经常使用到,而使用最多的就是AD56xx系列,包括有单通道的AD5662、双通道的AD5623和AD5663、以及四通道的AD5624和AD5664等。出于方便复用的原因,我们设计并实现AD56xx系列DAC的驱动。 1、功能概述 AD56xx系列DAC属于nanoDA…

外设驱动库开发笔记2:AD8400系列数字电位器驱动

一些时候我们需要在系统使用过程中改变某些电路电阻值以达到改变设定的目的,这时候我们就会使用电位器。在我们使用数字控制电路时多选择数字电位器。在这一篇我们就来设计AD8400系列数字电位器的驱动。 1、功能概述 AD8400/AD8402/AD8403分别是单通道/双通道/四通…

外设驱动库开发笔记3:AD527x系列数字电位器驱动

在一些时候我们需要使用精度更高的数字电位器来实现我们的应用。我们经常使用AD527x系列数字电位器来实现这类应用。在通常情况下,AD527x系列数字电位器完全能够满足要求。为了减少重复工作,在这里我们将分系并实现AD527x系列数字电位器的驱动。 1、功能…

PID控制器改进笔记之一:改进PID控制器之参数动态调整

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

外设驱动库开发笔记4:AD9833函数发生器驱动

很多时候我们需要输出某种函数信号,如方波、三角波、正弦波等,但想要获得这样的函数信号,不论是硬件电路还是软件实现,却并不是一件简单的事情。不过AD9833这类函数生成芯片可以简化这方面的操作,这一节我们就来设计并…

PID控制器改进笔记之二:改进PID控制器之手自动切换

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

外设驱动库开发笔记5:AD7705系列ADC驱动

我们的经常需要采集一些精度要求较高的模拟信号,使用MCU集成的ADC难以达到要求、所以我们需要独立的ADC芯片。这一节我们就来设计并实现AD7705芯片的驱动、并探讨驱动的使用方法。 1、功能概述 AD7705/AD7706是用于低频测量的完整模拟前端。可以直接从传感器接收低…

PID控制器改进笔记之三:改进PID控制器之正反作用

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

PID控制器改进笔记之四:改进PID控制器之设定值响应

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

PID控制器改进笔记之五:改进PID控制器之串级设定

前面我们发布了一系列PID控制器相关的文章,包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能,也在实际使用中取得了良好效果,但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…

滤波器开发之一:基于算数平均的平滑滤波器

信号采集是非常常见的需求,我们也总是希望采集到的数据是纯净而真实的,但这只是我们的希望。环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响,于是就有了滤波器的用…