APP下载

uIP中UDP协议实现的改进*

2010-05-11曹欲晓

网络安全与数据管理 2010年21期
关键词:端口号服务端调用

曹欲晓,韩 磊

(南京工程学院 计算机工程学院,江苏 南京 211167)

随着嵌入式技术、网络技术的发展,实现网络互联已经成为嵌入式系统发展的一个必然趋势。在目前的技术条件下,越来越多的嵌入式系统选择了TCP/IP作为与其他计算机系统互联的网络协议。嵌入式TCP/IP协议栈已经成为嵌入式系统研究与应用中的一个重要领域。

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

1 uIP协议栈的体系结构

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

图1 uIP协议栈体系结构

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

uIP初始化时调用uip_init()函数,它的主要功能是初始化协议栈的监听端口,并把所有连接设置为关闭状态。当网络控制芯片驱动程序接收到一个数据包时,驱动程序将数据包放入全局缓冲区uip_buf中,同时把包的大小赋给全局变量uip_len。然后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提供一系列接口供用户程序调用,其中大部分接口是作为C的宏命令出现的,之所以这样做主要是考虑到速度、代码大小、效率和堆栈的使用。用户需要把对网络数据包的处理函数作为接口提供给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数据包后,首先从包头中取出数据的长度,然后重新对包进行校验,如果校验和不对,则直接丢掉这个包。如果校验无误,则对收到的包进行解复用。此时进行如下判断:

上述代码中用到的主要变量、数据结构和函数的含义是:

在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)。由于作为服务端运行时必须指定监听端口[5],而 uIP没有提供此功能,因此要让uIP作为服务端运行,必须对uIP进行改进。

3 uIP中UDP协议的改进

3.1 增加初始化UDP服务端口

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

图2 UDP服务端口初始化

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

uip_process函数接收到网络控制芯片驱动程序送来的数据包后,当判断出收到的包是UDP包,执行2.1中的判断并且得到结果为真后,但还需要再做以下工作:如果uip_udp_conn中的目的端口号为0,则说明这是一个来自客户端的首次与服务端进行通信的数据包,服务端尚不知道此客户端的源端口,因此要把uip_udp_conn中的目的端口号设为收到的包中的源端口号,把uip_udp_conn中的目的IP地址设为收到的包中的源IP地址,具体代码如下:

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服务器,运行Windows XP的PC机作为客户端,两者通过一条交叉网线相联,在PC机上的测试程序发出UDP请求后,运行在S3C2410上的uIP可以对PC通过UDP协议发出的数据进行处理,并给PC作出正确的回复。实验证明,通过对uIP进行本文所述的改进之后,uIP具有了作为UDP服务端的能力。

[1]http://www.sics.se/~adam/uip/index.php/Main_Page.

[2]ADAM D.The uIP embedded TCP/IP stack the uIP 1.0 reference manual.June 2006.

[3]ADAM D.Full TCP/IP for 8-bit architectures[C].In Proceedings of the First International Conference on Mobile Applications,Systems and Services(MOBISYS 2003), San Francisco, May 2003.

[4]ADAM D, OLIVER S, THIEMO V, et al.Protothreads:simplifying event-driven programming of memory-constrained embedded systems[C].In Proceedings of the Fourth ACM Conference on Embedded Networked Sensor Systems(SenSys 2006), Boulder, Colorado, USA, November 2006.

[5]FOROUZAN B A,FEGAN S C著.TCP/ZP协议簇 [M].谢希仁等,译.北京:清华大学出版社,2006.

猜你喜欢

端口号服务端调用
在Docker容器中安装应用程序
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
云存储中基于相似性的客户-服务端双端数据去重方法
新时期《移动Web服务端开发》课程教学改革的研究
在Windows Server 2008上创建应用
浅谈以java为基础的Socket通信简介及实现
基于系统调用的恶意软件检测技术研究
Winsock编程在《计算机网络基础》教学中的应用
基于Android系统的互动展示APP的研究与设计