姜林美
(华侨大学计算机科学与技术学院,福建泉州 362021)
利用W IN 3 2动态链接库的TFTP服务器的设计与实现
姜林美
(华侨大学计算机科学与技术学院,福建泉州 362021)
为了实现在设备相关的桌面应用配置软件中嵌入简单文件传输协议(TFTP)服务功能,开发针对嵌入式系统的FLASH烧录及其配置和文件升级的接口程序.考虑到软件复用的需要,采用W IN 32动态链接库技术,整个 TFTP服务模块仅由一个动态链接库文件tftp.dll组成.使用多线程技术,以适应 TFTP收发过程与应用程序的其他过程并发执行的需要.将所述方法应用于实际的路由器配置产品中,并验证其有效性.
简单文件传输协议;用户数据包协议;传输控制协议/因特网互联协议;动态链接库;多线程;文件传输;嵌入式系统
简单文件传输协议(TFTP)在各类嵌入式产品中应用广泛.在这些嵌入式产品中,主要使用 TFTP来代替JTAG方式的FLASH烧录[1-2],以及使用 TFTP实现软件或配置的在线更新[3].通常,网络服务器总是在装有网络操作系统(如Unix,Window s 2003等)的专用服务器设备中实现,而此种方式具有设备移动不方便,服务器需要有人值守,以及网络服务安全需要特殊考虑等弊端,故不适用于 TFTP.对于嵌入式设备而言,往往需要在设备和小型桌面应用软件中嵌入 TFTP文件传输功能.即使用一个专用的桌面应用配置软件与设备进行通信,以完成BOOT文件、映像文件或配置文件的传输,而不是使用专用的主机设备来充当TFTP服务器的角色.因此,开发一个通用的TFTP传输模块,以供任意桌面应用软件在需要时调用就显得很有价值.本文讨论在Visual C++2005(VC 2005)环境下,使用W IN 32动态链接库[4]实现 TFTP服务器的一种方法.
1.1 接口
使用两个接口ISink和ITftp,来隔离TFTP服务器的实现和使用,其定义如图1所示.
图1 接口ISink和ITftp的定义Fig.1 Definitions of interface ISink and ITftp
在C++中,接口的定义是使用结构体加纯虚函数来完成的.ISink接口由应用程序实现,并被传递给DLL.在DLL中,当适当事件发生时就会调用接口中相应的事件方法.On Tftp RecvOver()方法在文件接收(即上传)完毕时被调用,On Tftp SendOver()方法在文件发送(即下载)完毕时被调用,On Tftp Error()方法则在文件接收或发送出错时被调用.3个方法的参数str Ip和strFilename用于指明是哪一个连接(一个 TFTP服务器可以同时与多个客户端建立连接)触发的事件, On Tftp Error()方法中的参数 iError-Code给出错误发生时的错误代码,方便在应用程序中对出错情况进行处理.
ITftp接口由DLL实现,是 TFTP服务器模块与外层应用程序交互的唯一接口.其中:Start()方法用于在参数uPort指定的端口上启动 TFTP服务, Stop()方法则用于停止 TFTP服务并释放所有资源;Advise()方法用于建立一个外层应用中实现的 ISink接口与DLL中TFTP服务的一个连接,其唯一参数pSink用于传入外层应用中实现的ISink指针;SetRootDir()方法设置TFTP服务器文件放置的根目录,参数strDir为目录名.
1.2 TFTP报文
相应于 TFTP报文格式,采用几个数据结构来处理 TFTP报文,其定义如图2所示.各个结构体中的字段含义由各字段后的注释给出.使用 1个类CRequests来管理所有的 TFTP连接,其定义如图3所示.图3中:最后一行的TRequest类型使用标准模板库中的map容器定义:typedef std::map〈std:: string,TRequest*〉TRequests.
图2 处理TFTP报文的数据结构注释Fig.2 Comments of the data strutures for processing TFTP datagrams
图3 类CRequests的定义Fig.3 Definition of class CRequests
1.3 TFTP实现类
使用CTftp S类来具体实现 TFTP服务器的功能.该类从接口ITftp继承,实现声明的所有方法,其定义如图4所示.TFTP服务器实现代码均封装在CTftp S类中,因此该类的实现主要是ITftp接口声明的4个方法的实现.
(1)Start()方法用于启动 TFTP服务,进行SOCKET库的实始化并创建服务器端SOCKET,让其监听在指定的端口(默认端口号为69).然后,对类变量(包括线程同步变量)进行初始化.最后,创建TFTP收发线程,专门负责 TFTP连接的建立和TFTP报文的接收与发送,其入口函数即CTftp S类的静态成员函数Thread-Func().在创建的线程的时候,CTftp S类的实例指针将作为线程的参数传入ThreadFunc().
(2)Stop()方法用于停止TFTP服务,要触发停止TFTP收发线程的事件并等待该线程退出,最后释放所占用的各种资源.另两个方法的实现很简单,限于篇幅不赘述.
图4 CTftpS类的定义Fig.4 Definition of class CTftpS
图5 TFTP线程函数处理流程Fig.5 Program flow in TFTP thread function
TFTP服务实现的关键在于 TFTP收发线程函数 Thread Func(),其处理流程图如图5所示.在线程函数中,通过线程函数的参数取得 CTftp S对象的指针,而这只要通过对函数参数进行一个类型强制转换即可完成.线程的主循环具有一个唯一的退出条件,即退出线程事件(事件句柄为CTftp S::m_hEventEnd Thread)在主线程中被触发,通过WINDOWS API函数 Wait For Single Object()可以捕获该事件.
在线程的主循环内,调用CTftp S:: Elapse Time()方法扫描当前已建立的所有用于下载文件的 TFTP连接,比较当前时间与连接记录(TRequest类型变量)的tm Expiry字段的差值.如果该差值超过了设定的超时时间(比如3 s),则重发上一个数据报文,检查连接记录的iA ttemp tTimes字段;而如果该字段的值(重发次数)大于3,则触发ISink接口的On Tftp Error()事件并挂断连接.
调用CTftp S::Elapse Time()方法后,继续调用CTftp S::RecvData()方法尝试接收TFTP报文.通过对收到的有效报文进行解析,把解析结果保存在一个 TRequest类型变量中,并将该结果通过指针类型参数返回给线程函数.如果通过CTftp S::RecvData()方法接收到任何有效的 TFTP报文,则根据报文格式的不同分别进行处理.
对于RRQ或WRQ报文,需要调用CTftpS::Process New()方法建立一个新的TFTP连接.建立连接的过程是:首先从报文中获取文件名及模式,在设定的服务器根目录下建立一个相应的文件.其次,对于RRQ请求需要读取文件的头512 B,并将其发送给客户端;而对于WRQ请求,则直接发送一个块号为零的确认报文.最后,生成一个 TRequest数据,并将其加入CTftp S::m_requests记录的连接请求列表中.
对于DA TA报文,先判断该报文是不是由于超时重发而形成的重复报文,若是则直接发回一个块号与所收报文块号相同的确认报文;否则,将收到的数据写入服务器端文件,然后发回相应的确认报文.最后,如果收到的数据少于512 B,说明已是最后一个数据报文,文件传送完毕,触发ISink接口的On T-ftp RecvOver()事件,关闭该 TFTP连接.
对于ACK报文,首先判断块号与上一次发送的数据报文的块号是否一致.如果不一致,说明是一个已处理过的重复报文,可忽略该报文;如果一致,则继续判断上一次发送的数据报文的数据长度是否小于512 B,小于512 B说明已是最后一块数据,文件传送完毕,触发ISink接口的On Tftp SendOver()事件,关闭该TFTP连接.
对于ERR报文处理比较简单,直接触发ISink接口的On Tftp Error()事件并挂断连接.TFTP线程中调用的其他CTftpS类的方法的实现均较为简单,比如 TerminateConn()方法用于关闭连接,其操作就是简单地关闭相应的SOCKET,并从CTftp S::m_requests记录的连接请求列表中删除该连接对象.
所讨论的TFTP服务器模块,最初基于某公司的3G路由器产品的桌面配置软件而开发,并最终应用于该产品.实践证明,其应用方便,用于产品运行稳定可靠.需要说明的是,由于协议的简单性, TFTP没有提供任何安全方面的特性[5].
[1]汪小燕,连晓平,黄燕,等.基于TFTP协议的嵌入式系统开发方法设计与实现[J].华中科技大学学报:自然科学版,2006,34(12):56-58.
[2]李虔华,臧习飞.TFTP协议在嵌入式系统中的应用[J].电脑与电信,2008(2):40-42.
[3]甘育裕,李婷.在嵌入式Linux中实现 TFTP Server[J].中国有线电视,2005(Z3):4945-4949.
[4]郭晓鹏,李存斌.Vicsual C++高级编程及其项目应用开发[M].北京:中国水利水电出版社,2004.
[5]RICHARD SW.TCP/IP Illustrated:Volume 1[M].Boston:Addison Wesley,1995.
(责任编辑:黄晓楠英文审校:吴逢铁)
Design and Implementation of TFTP Server Based on WIN 32 Dynamic Link Library
JIANG Lin-mei
(College of Computer Science and Technology,Huaqiao University,Quanzhou 362021,China)
To add a TFTP(trivial file transfer protocol)service to a device-related desktop configuration software,a program interface targeted at the flash burning and configuration upgrade of embeded system s is developed.Considering the requirement of the software reusablity,the W IN 32 DLL(dynamic link library)technology is used and the whole TFTP module is encapsulated in one DLL file(tftp.dll).In addition,to satisfy the requirement of concurrent running of the TFTP process and the other process in an application,the multi-thread technology is used.Finally,the validity is proofed by implementing this scheme in an configuration software of a router product.
trivial file transfer protocol;user datagram protocol;transmission control protocol/internet protocol;dynamic link library;muti-thread;file transfer;embeded system
TP 393.093
A
1000-5013(2011)02-0178-04
2009-09-18
姜林美(1976-),男,讲师,主要从事计算机网络安全及应用软件开发的研究.E-mail:clough@hqu.edu.cn.