浅谈uIP中UDP协议改进方案

时间:2023-06-25

  UDP协议的全称是用户数据包协议,在网络中它与TCP协议一样用于处理,数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其初的光彩已经被一些类似协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。

由于嵌入式系统的软硬件资源都较为有限,大多数嵌入式系统中运行的TCP/IP协议栈均根据嵌入式系统的特点进行了相应的裁剪。目前应用比较广泛的嵌入式TCP/IP协议栈有:ucTCP-IP、LWIP、uIP、Linux TCP/IP等。其中uIP是专为8 bit和16 bit的嵌入式微控制器设计的微型TCP/IP协议栈,运行时需要的内存很少,实现了常用的TCP/IP协议;代码注释详尽,可以用于商业或非商业用途。由于具有上述特点,uIP被广泛应用在嵌入式系统的网络互联中。

 1 uIP协议栈的体系结构

uIP协议栈往掉了完整的TCP/IP中不常用的功能,简化了通讯流程,但保存了网络通讯必须使用的协议,设计重点放在了IP/TCP/ICMP/UDP/ARP这些网络层和传输层协议上,保证了其代码的通用性和结构的稳定性。

由于uIP协议栈专门为嵌进式系统而设计,因此还具有如下优越功能:

(1)    代码非常少,其协议栈代码不到6K,很方便阅读和移植。

(2)    占用的内存数非常少,RAM占用仅几百字节。

(3)    其硬件处理层、协议栈层和应用层共用一个全局缓存区,不存在数据的拷贝,且发送和接收都是依靠这个缓存区,极大的节省空间和时间。

(4)    支持多个主动连接和被动连接并发。

(5)    其源代码中提供一套实例程序:web服务器,web客户端,电子邮件发送程序(SMTP客户端),Telnet服务器, DNS主机名解析程序等。通用性强,移植起来基本不用修改就可以通过。

(6)    对数据的处理采用轮循机制,不需要操纵系统的支持。

由于uIP对资源的需求少和移植轻易,大部分的8位微控制器都使用过uIP协议栈, 而且很多的着名的嵌进式产品和项目(如卫星,Cisco路由器,无线传感器网络)中都在使用uIP协议栈。

在使用uIP的嵌入式系统的软件体系结构中,uIP协议栈相当于一个代码库,它通过一系列的函数实现与底层硬件和上层应用程序的通信。


uIP协议栈主要提供了uip_input()和uip_periodic()2个函数供系统底层调用。uIP协议栈与应用程序的主要接口是UIP_APPCALL()和UIP_UDP_APPCALL()。

uIP初始化时调用uip_init()函数,它的主要功能是初始化协议栈的监听端口,并把所有连接设置为关闭状态。然后uIP的主控部分调用uip_input()函数,该函数将会根据数据包首部的协议标识处理这个包,并在需要时调用上层应用程序。当uip_input()返回时,一个输出数据包被放在同一个全局缓冲区uip_buf中,其大小赋给uip_len。如果uip_len是0,则说明没有包要发送,否则主控部分调用底层系统的发包函数将数据包发送到网络上[3]。

uIP周期计时用于驱动所有的uIP内部时钟事件。当周期计时激发后,每一个TCP连接都会调用uIP函数uip_periodic()。类似于uip_input()函数,uip_periodic()函数返回时,输出的IP包要放到uip_buf中,供底层系统查询uip_len的大小以决定是否发送。

由于使用TCP/IP的应用很多,因此应用程序作为单独的模块由用户实现。用户需要把对网络数据包的处理函数作为接口提供给uIP,并将这个函数定义为宏UIP_APPCALL()或者UIP_UDP_APPCALL()。UIP_APPCALL()是用户对TCP数据包的处理,UIP_UDP_APPCALL()是用户对UDP数据包的处理[4]。这样,uIP在接收到底层传来的数据包后,在需要送到上层应用程序处理的地方,直接调用UIP_APPCALL()或者UIP_UDP_APPCALL()即可,无需修改uIP。

  2 uIP的UDP协议分析

  2.1 UDP协议的实现

当uIP接收到一个UDP数据包后,首先从包头中取出数据的长度,然后重新对包进行校验,如果校验和不对,则直接丢掉这个包。如果校验无误,则对收到的包进行解复用。此时进行如下判断:

if(uip_udp_conn->lport != 0 &&

UDPBUF->destport == uip_udp_conn->lport &&

(uip_udp_conn->rport == 0 ||

UDPBUF->srcport == uip_udp_conn->rport) &&

(uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||

uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||      uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr)))          上述代码中用到的主要变量、数据结构和函数的含义是:

uip_udp_conn->lport:本地UDP的源端口;

uip_udp_conn->rport:本地UDP的目的端口;

UDPBUF->srcport:接收到的数据包中的源端口;

UDPBUF->destport:接收到的数据包中的目的端口;

uip_udp_conn->ripaddr:本地UDP的目的IP地址;

BUF->srcipaddr:接收到的数据包中的源IP地址;

all_zeroes_addr:IP地址0.0.0.0;

all_ones_addr:IP地址255.255.255.255;

uip_ipaddr_cmp:IP地址比较函数,如果参加比较的两个IP地址相等,则返回1。

在uIP的实现中,如果以上判断语句为真,则对接收到的数据包进行处理,处理过程包括调用用户上层处理程序UIP_UDP_APPCALL()、构造新包的包头、计算新包的校验和等,然后将构造好的返回UDP包送到IP层进行处理。

  2.2 UDP实现的不足

通过对uIP中UDP协议实现过程的分析可以发现,uIP没有提供初始化指定端口的函数,仅提供了一个对给定IP地址上给定端口建立UDP连接的函数,其原型是struct uip_udp_conn*uip_udp_new(uip_ipaddr_t*ripaddr,u16_t rport)。

 3 uIP中UDP协议的改进

  3.1 增加初始化UDP服务端口

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

UDP协议作为服务端运行时,同TCP一样,必须在某个指定端口上监听客户端是否有数据包发送,如果有则还要接收数据包,这就要求在uIP记录UDP连接的数据结构uip_udp_conn中设置本地端口号一项。


  3.2 IP地址、端口号的判断及匹配

uip_process函数接收到网络控制芯片驱动程序送来的数据包后,当判断出收到的包是UDP包,执行2.1中的判断并且得到结果为真后,但还需要再做以下工作:如果uip_udp_conn中的目的端口号为0,因此要把uip_udp_conn中的目的端口号设为收到的包中的源端口号,把uip_udp_conn中的目的IP地址设为收到的包中的源IP地址,具体代码如下:

if(uip_udp_conn->rport==0)

{

uip_udp_conn->rport=UDPBUF->srcport;                memcpy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr,sizeof(uip_ipaddr_t ));

}

3.3 UDP服务端目的端口的释放

UDP服务端的端口应该可以为来自多个客户端的请求提供服务,而UDP本身是一种无连接的传输层协议,因此在每次uIP作为服务端的UDP通信结束之后,还要释放uip_udp_conn中记录的目的端口号,以便下次接收来自不同IP、不同端口的新请求,否则当来自其他端口的请求到达时,uIP会不予响应。

在uIP的网站上到uIP 1.0的源代码之后,按照本文给出的几个步骤对uIP 1.0进行改造之后,利用gcc编译器把uIP 1.0编译成S3C2410上的可执行代码,把基于S3C2410的开发板作为UDP服务器,运行在S3C2410上的uIP可以对PC通过UDP协议发出的数据进行处理,并给PC作出正确的回复。UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。

上一篇:浅谈PLC的高速计数器功能在定位控制中的应用
下一篇:浅谈如何改进遗传算法优化的BP神经网络入侵

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料