资源描述
毕业设计(论文)
设计(论文)题目: 基于嵌入式 Linux 系统
远程升级设计与实现
学生姓名:
学生学号:
专业班级:
指导老师:
系主任(院长):
年 6 月 5 日
毕业设计(论文) 第 46 页
毕业论文原创性声明
本人郑重声明:所呈交的论文是本人在老师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。本人完全意识到本声明的法律后果由本人承担。
学生签名: 日期:200 年 月 日
毕业论文版权使用授权书
本毕业论文作者完全了解学校有关保留、使用论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权湖南大学可以将本论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本论文。
本论文属于
1、保密 ,在______年解密后适用本授权书。
2、不保密√。
(请在以上相应方框内打“√”)
学 生签名: 日期:200 年 月 日
指导教师签名: 日期:200 年 月 日
基于嵌入式Linux远程升级设计与实现
摘要
随着信息技术、计算机网络技术的迅猛发展和广泛普及,人们对Internet的需求也越来越大,Internet带来的好处也越来越得到体现,许多信息家电、智能仪表等设备接入到互联网成为可能,实现网络化、智能化的集中管理,从而带给人们更精彩、更方便的生活方式。
近年来我国电力需求不断增加,供应日趋紧张。为了保证电网安全、正确地商业化运营,必须有一套计量精确、功能强大的自动抄表系统。因此也需要设计一个升级程序,实现对自动抄表系统的远程升级。本论文考虑的就是如何设计和实现基于嵌入式Linux的远程升级系统。
如果人工逐一对这些程序升级,存在两个问题。其一,需要耗费大量人力和物力,其二,人工操作不如电脑精细和方便。本课题研究的是如何利用主站应用程序对数据采集器进行远程升级。本论文详细阐述了设计系统的整体思路,系统各功能的实现,利用自己设计出的规约来实现断点续传的基本原理。同时也介绍了多线程设计,以及简单的加密和压缩方法。
关键词:远程升级,多线程设计,断点续传
Based on embedded Linux remote update design and implement
ABSTRACT
Along with the technical fast development and extensive universalities of information and networks, the people's need to the Internet is also more and more big, the advantage that Internet bring also gets materialize more and more now, make equipments, such as many information appliances and the intelligence appearance... etc .connect go into the Internet to make possible, thus carry out the network to turn, the centralized management that intelligence turn, bring the people the more fascinating and more convenient life style.
Considering that the demand of electric power is increasing ceaselessly in recent years, and the supply become more and more embarrassed. In order to assure the safety of the electricity supply and put the running of electricity into a right commercial way, a powerful and exactly computing system to gain the data automatically is essential.So,it also need to design a system to make it update automatically. This paper is considering how to design and implement the remote update system which based on the embedded Linux.
Updating system by manual work exist two disadvantage.First,it must waste a lost of manpower and time.Second,manual work usually make mistakes, to be contrary, the computer can make the work much more efficiently and correctly. This subject is studying how to implement the remote update of data collect system by the application. this paper detailed discusses the thought of the system analysis, and the implement of the system function, and the principle of continue transferring from breakpoint which make use of the stipulations of an agreement designed by myself. At the same time , it also introduce the multithreading design, simply encrypt and compress method and so on.
Keywords: long-distance update, multithreading design, continue transferring from breakpoint
目录
1. 绪论 1
1.1本课题的目的和意义 1
1.2本课题的课题来源 2
1.3目前国内外的发展情况 2
2. 嵌入式Linux基础 5
2.1嵌入式Linux系统概述 5
2.2 Linux在嵌入式系统中的优势 6
2.3 嵌入式Linux系统的技术发展 7
3. 总体方案设计 8
3.1系统总体结构 8
3.2升级方式选择 9
3.3工具软件选择 10
4. 多进程和多线程设计 11
4.1 Linux下多进程编程 11
4.1.1 Linux下进程的结构 11
4.1.2 如何创建进程 11
4.1.3 Linux的进程与Win32的进程/线程的区别 12
4.2多线程设计 12
4.3多线程具体实现代码 13
5. 断点续传的基本原理 17
5.1 主站请求文件信息 17
5.2主站设置升级文件信息 18
5.3文件传输 19
5.4实现断点续传 20
6.远程升级流程图 22
6.1升级流程时序图 23
6.2升级流程活动图 24
7. 测试结果和分析 25
7.1文件传输 25
7.2断点续传 26
7.3 错误检测 27
8. 工作总结和展望 29
8.1总结 29
8.2毕业设计的主要工作 29
8.3下一步工作 29
致谢 30
参考文献 31
附录 服务器端源代码 32
1. 绪论
21世纪是一个充满挑战性的时代,科学技术日新月异,特别是计算机网络己经成为人们广泛使用的工具。随着网络及通信技术的飞速发展,Internet的越来越普及到人们的日常生活中,人们对Internet的需求也越来越大,Internet所带来的好处也越来越得到体现使许多的信息家电智能仪表等非PC设备接入到互联网成为可能,从而实现网络化、智能化的集中管理,带给人们更精彩、更方便的生活方式。产品的设计包括硬件设计和软件设计,每种产品的设计部不可能做到尽善尽美。尤其是软件部分,由于其灵活性较大,也往往是最容易出错的地方,在一种新产品刚推上市场的过程中,往往会发现系统中存在某种可修复的"BUG",一种情况是通过软件的修改就可达到日的,另一种情况是虽然产品的软、硬件都没有问题,但随着形势的发展,用户提出了更高的要求,这种情况能够通过修改软件就能达到。
由于目前非PC智能设备不能满足现在的科学技术发展的需求,而且受工作地点的限制,无远程升级功能,不能很好的对其升级。如果要使设备得到升级换代,根据以往的做法,一种方式是将整个仪器换掉,另一种方式就是派专业人员到现场对仪表“开膛破肚”进行升级,这两种方式都要投入大量的人力物力,以及可能造成设备损坏,资源浪费大,效率低,给应用方带来使用上的不便。
1.1本课题的目的和意义
近年来我国电力需求不断增加,供应日趋紧张。 为了保证电网安全、正确地商业化运营,必须有一套计量精确、功能强大的自动抄表系统。自动抄表系统不仅节约了大量的人力和时间,快捷、准确地传递了信息,减少了人工抄表误差,提高了工作效率,而且也是全面实现发、输、配电网用户电能量的自动采集、分析与计费功能的有效手段,是电力行业优化管理、走向市场的技术保障。
典型的电力自动抄表系统主要由前端抄表子系统、通信子系统和中心处理子系统等3 部分组成。电能表数据采集终端是前端采集子系统的主要组成部分. 电能表数据的采集一般分为脉冲采集型和通过RS - 485 直接连接于采集器的数据采集型两种形式,本课题主要采取后一种形式。
后PC 时代,随着嵌入式系统的广泛应用,嵌入式操作系统也越来越受到重视. 嵌入式操作系统具有结构小巧、实时性强、稳定性高等特点。 嵌入式Linux 为许多应用提供了良好的解决方案,其开放的源代码、强大的技术支持、良好的可扩展性及对众多硬件的支持都是它嵌入化的优势。电能表数据采集终端一般都挂接1~16 路电能表,实现对它们的轮流电量采集,将高性能的CPU 处理器和多任务操作系统应用于自动抄表系统中,结合嵌入式操作系统来实现新型的数据采集器,可以大幅度地提高系统整体性能。 基于嵌入式Linux 的多任务机制,可以在多个进程调度下实现对电表的同时采集,处理速度大为提高,并且基于高速的处理器,可以连接大容量的SDRAM和FLASH ,提高了系统的数据存储空间. 为电力计量计费的准确、实时操作提供了可靠的技术保证。
由于电力市场和需求的不断变化,需要不定期对数据采集器上的程序进行升级,同时由于这些数据采集器分布在城市各处,如果人工逐一对这些程序升级则需要耗费大量人力和物力,一种经济可行的方法是利用主站应用程序对数据采集器进行远程升级。采用多线程设计,一台维护工作站可同时对多台终端进行维护和升级,支持分模块升级和断点续传功能。
1.2本课题的课题来源
在GPRS网络的特性下,传统的远程升级已不再适合终端的软件升级,必须要采用新的方法,通过某种特殊的流程来解决GPRS通讯故障带来的升级问题。
为了解决以上的问题,我们在借鉴了传统的文件传输方式-FTP方式,在这基础上设计了一套比较适合GPRS通讯网络通讯的远程升级方式[1]。
1.3目前国内外的发展情况
互联网已经进入一个崭新的时代,它成为我们日常生活的一部分。无论是在家中在办公室或者其他地方,都能通过PC机方便地连接到网络上。众所周知,PC机系统软件和应用软件的升级已从原来的传统邮寄升级包到使用E-mail邮寄升级包,再过渡到基于Internet网络的自动升级。国产杀毒软件瑞星、江民杀毒王等升级,用户只需在软件中点击升级按钮或在程序中设置自动升级,软件升级就会自动完成。大名鼎鼎的PC机操作系统Windows的自动更新体现了使用网络自动升级的优势。
目前电子产品升级技术正兴起于电子电路研制、生产、功能不全、设备更新能力差、故障诊断等方面。它的出现大大提高了电子产品的质量可靠性,缩短了电子设备的维护时间,大幅度降低了电子设备的更新、检修费用。大多数嵌入式系统为了实现多个MCU之间的信息交流,利用RS-232, RS-485等总线将MCU组网,但这种网络的有效途径比较有限,有关的通信协议也比较少,并且一般是孤立于Internet以外的。
Internet 现已成为社会重要的基础信息设施之一,是信息流通的重要渠道,如果嵌入式系统能够连接到Internet上面,则可以方便、低廉地将信息传送到几乎世界上的任何一个地方。将嵌入式系统与Internet结合起来的想法其实很早以前就有了,主要的困难在于,Internet上面的各种通信协议对于计算机存储器、运算速度等的要求比较高,而嵌入式系统中除部分32位处理器以外,大量存在的是8位和16位MCU,支持TCP/IP等Internet协议将占用大量系统资源。
单片机 、DSP或ARM已经在家庭和工业的各个领域得到了应用,通称嵌入式系统。单片机技术的发展对智能仪器的发展起着重要的作用,同样,智能仪器的发展也对单片机的发展提出了更高的要求,片内带快闪存储器FLASH MEMORY的单片机,便得到了业界的热烈响应和广泛的市场认可。快闪存储器比普通的EPROM 存储器的改进之处是不仅可以读,而且可以用软件快速地擦除和写入,取消了专用编程设备,器件本身也不必从系统电路板上取下。如果产品发往外地,或是远涉重洋出口海外,就需要生成一个庞大的全球性售后服务网络对产品跟踪或更新。
软件升级形式有:第一种是通过更换产品的存储器芯片进行升级;第二种是开发方将升级包发给用户,通过PC机及串口做媒介下载升级包,对产品进行升级;第三种是产品直接上网,按键确认升级;第四种是产品具有远程诊断和维护,跟踪产品的状况。第三种是目前流行的一种方式,第四种是软件升级的一种趋势。据了解,国内外正在研究电视、冰箱等都具有远程升级、远程监控和管理功能,还有汽车、仪表、工控单元等也朝网络自动升级方向发展,并且国外有部分公司正在研制具有网络接口的微处理器。可见,随着因特网应用的日益普及,信息共享的程度不断提高。对于以单片机应用系统为中心的小型嵌入式设备,怎样利用方便的因特网资源将嵌入式设备的信息共享到因特网上,成为当今电子世界中的热门话题。传统的因特网应用以PC为中心,当代的因特网应用将转向以嵌入式设备为中心。据网络专家的预测,将来在因特网上传输的信息中,将有70%的信息来自于小型嵌入式系统121利用单片机实现嵌入式因特网方案的技术难点在于:如何利用单片机自身有限的资源对信息进行TCP/IP协议处理,使之变成可在因特网上传输的IP数据包。
2. 嵌入式Linux基础
2.1嵌入式Linux系统概述
自从计算机诞生以来,随着计算机、网络技术的快速发展,操作系统一直处于不断发展和改进之中,人们将越来越多的功能加入到操作系统中,导致操作系统越来越大。但是,随着应用领域的扩大,为了适应不同的应用场合,考虑到系统的灵活性、可伸缩性以及可裁减性,一种以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗要求严格的专用计算机系统---嵌入式操作系统便随之诞生。
嵌入式Linux是按照上面所说的嵌入式操作系统的要求设计的一种小型操作系统。由一个kernel(内核)及一些根据需要进行定制的系统模块组成。其Kernel很小,一般只有几百K左右,即使加上其它必要的模块和应用程序,所需的存储空间也很小,多任务多进程的系统特征,有些还有具有实时性。
一个小型的嵌入式Linux系统只需要下面三个基本元素:
1.引导程序;
2.Linux微内核(由内存管理、进程管理和事务处理构成);
3.初始化进程。
如果要让它有更多的功能且继续保持小型化,可以加上:文件系统(可以在ROM,RAM,FLASH或Disk On chip中),TCP/IP网络支持存储更多数据用的磁盘,提供设计精简的应用程序。由于嵌入式Linux操作系统的高度灵活性,开发者可以很容易地对它进行定制或作适当开发,来满足实际应用需要[2]。
2.2 Linux在嵌入式系统中的优势
目前典型的嵌入式操作系统有:
Palm OS,WindowsCE,EPOC,LinuxCE,QNX,ECOS,LYNX。高端嵌入式系统要求许多高级的功能,如图形用户界面和网络支持。很多高端RTOS供应商已经提供了这些功能,但其价格也很高端,一般人难以接受。微软的Windows CE也有此类功能,却不具备大多数嵌入式系统要求的实时性能,而且难以移植,也曾经有人想以DOS为基础用单独的第三方工具拼凑一个系统,但这种努力将是白费。众所周知,Microsoft的东西向来都是以昂贵和不稳定出名,而现在需要的是一个便宜、成熟并且提供高端嵌入式系统所必须特性的操作系统,嵌入式Linux操作系统以价格低廉、功能强大又易于移植而正在被广泛采用,成为新兴的力量,所以,众多商家纷纷转向了嵌入式linux。
Linux为嵌入操作系统提供了一个极有吸引力的选择,她是个和Unix相似、以核心为基础的、完全记忆体保护、多任务多进程的操作系统。支持广泛的计算机硬件,包括X86,Alpha,Sparc,MIPS,PPC,ARM,NEC,MOTOROLA等现有的大部分蕊片。程式源码全部公开,任何人可以修改并在GNU通用公共许可证(GNU General Public License)下发行,这样,开发人员可以对操作系统进行定制,再也不必担心像M$ windows操作系统中“后门”的威胁(后门不是我们常说的走后门,是指嵌入到软件中的一个特殊程序,它有一些不道德的额外功能,例如可以把使用者的数据送到指定的地址)。同时由于有GPL的控制,大家开发的东西大都相互兼容,不会走向分裂之路。Linux用户遇到问题时可以通过Internet向网上成千上万的Linux开发者请教,这使最困难的问题也有办法解决。
Linux带有Unix用户熟悉的完善的开发工具,几乎所有的Unix系统的应用软件都已移植到了Linux上。Linux还提供了强大的网络功能,有多种可选择窗口管理器(X windows)。其强大的语言编译器gcc、g++等也可以很容易得到。不但成熟完善、而且使用方便。
2.3 嵌入式Linux系统的技术发展
嵌入式系统的商品化操作系统在70年代后期才出现,许多是用汇编语言写成的,并且只能用于特定的处理器,更换新处理器,它的操作系统就必须更新以适应新的系统。当C语言出现时,操作系统编写的效率、稳定性、可移植性都有了很大的提高。这一点在管理上立刻表现出来,它为微处理器被淘汰时保护软件投资带来了希望。对于市场来说这是一个好消息。用C语言写成的操作系统今天越来越普遍。一般来说,可重复使用的软件已经占了主导地位并越做越好。
许多嵌入式系统根本没有操作系统,只有循环控制。对于一些简单设备这是足够的,但是随着系统越来越复杂,更多嵌入式系统需要与各类网络联接,因此需要网络功能。增加网络功能将导致系统复杂程度提高以致要求操作系统。
传统的嵌入式系统是基于单片机的,而新一代的嵌入式系统将以如下为特点:以IP核模块(Intellectual Property Kernel知识产权核模块)为核心,用混合ASIC/CPLD/FPGA生成的硅片直接构成整块的单片嵌入式产品(SOC)。
随着嵌入式操作系统的快速发展,应用的范围不断扩大,使用者日益增加,一个非常关键,必须解决的重大问题出现了。
很久以前, 一般的编程语言,编译,开发只能支持英文的,不能支持它国语言,比如拿一个只支持英文的浏览器去访问中文的网站,显示出来的东西将是混乱不可阅读,嵌入式Linux也同样不能避免这种问题,它直接影响到系统开发的路线。
为了使Linux支持中文,国人做了许多的努力,基本上解决了中文支持的问题。1999年是中国Linux发展和普及过程中最重要的一年,其中涌现了许多制作中文 Linux发布版本的公司,加速 Linux的中文化过程并推动Linux在中国的普及。如今这些公司又纷纷转向了中文嵌入式Linux操作系统的开发,如Turbo,红旗,还有一些一开始就开发嵌入式Linux的公司,如网虎,博利思等,其中,博利思于5月份最先推出其中文嵌入式Linux操作系统。
3. 总体方案设计
确定系统的总体方案,是系统设计中十分重要的一步。合理的总体设计来自于对系统要求的全面分析和对实现方法的正确选择。
3.1系统总体结构
基于嵌入式Linux系统远程升级设计与实现的总体思路如下:终端上运行服务器端,并且侦听相应端口,作为系统升级侦听程序。主站是客户端,当需要对终端程序进行升级时,由主站发起连接,成功建立起升级会话后,主站获取到终端相应的升级文件信息,并根据信息进行相应的处理。如果文件可以升级,而且主站上的版本和比终端上的版本要新,则传输文件,进行版本更新。更新完毕后,检测文件信息,重新启动终端程序,从而达到了远程自动升级的目的。具体结构图见图3.1和图3.2。
终端2
(等待侦听…)
终端n
(等待侦听…)
终端1
(等待侦听…)
主站
图3.1 升级结构图
图3.2 文件传输流程
3.2升级方式选择
目前GPRS数据通讯网现在在无线数据通讯网络上已占用了主导地位,它有以下的一些优点:
它是无线网络,整个网络基于中国移动通讯公司的GSM网络,其网络覆盖面广,可以保证实时在线。其计费方式是采用流量计费的方式,其在线状态并不发生费用,可以有效降低运营费用。
通常在电力采集系统中,各类电表规约随时可能接入终端,并且在各业务要求迅速发展的前提下,电力公司随时可能对终端提出新的功能要求,因此对终端软件进行版本升级,已成为了必备功能。
GPRS网络现状:
1.GPRS网络的物理特性决定了其连接状态是不稳定的,在网络传输的过程中经常会出现网络诸塞,数据报丢失的状况。
2.在网络连接比较正常的情况下,与通常的以太网络相比较,其数据报传输的速度也比较慢,通常的传输时间在2~5秒,平均时延大约在4秒钟左右。
3.在数据吞吐量大,网络不稳定的情况下,甚至可以延时达数分钟。
一旦发生通讯故障,必然会影响终端软件的远程升级,另外,GPRS需要通过移动的通讯平台来进行数据传输,这样必然会带来一定安全性问题。
在这种GPRS网络的特性下,传统的远程升级已不再适合终端的软件升级,必须要采用新的方法,通过某种特殊的流程来解决GPRS通讯故障带来的升级问题。
为了解决以上的问题,我们在借鉴了传统的文件传输方式-FTP方式,在这基础上设计了一套比较适合GPRS通讯网络通讯的远程升级方式。
在设计升级方式时,我考虑了以下五点:
1.借鉴FTP文件断点续传的方式。
2.对传输的数据进行加密以提高传输的安全性。
3.对传输的数据进行压缩以提高传输效率。
4.传输过程由主站发起和控制,减少不必要的连接,以提高效率。
5.传输过程中多个数据块并行传输,以提高传输效率。
3.3工具软件选择
服务器端:嵌入式Linux系统,ARM9 s3c2410,C语言
客户端:Windows XP操作系统,Visual Studio C++6.0,MFC
4. 多进程和多线程设计
4.1 Linux下多进程编程
4.1.1 Linux下进程的结构
Linux下一个进程在内存里有三部份的数据,就是“数据段”,“堆栈段”和“代码段”,一般的CPU都有上述三种段寄存器,以方便操作系统的运行。“代码段”,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。
堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段[3]。
4.1.2 如何创建进程
系统调用fork函数,就可以在Linux下创建一个新的进程。一个程序一旦调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat,shmdt等)来操作。现在,已经是两个进程了,对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中[4]。
如果一个大程序在运行中,它的数据段和堆栈都很大,一次fork就要复制一次,那么fork 的系统开销会变得很大, UNIX对这种情况有一种解决的办法,一般CPU都是以“页”为单位分配空间的,像INTEL的CPU,其一页在通常情况下是4K字节大小,而无论是数据段还是堆栈段都是由许多“页”构成的, fork函数复制这两个段,只是“逻辑”上的,并非“物理”上的,也就是说,实际执行fork时,物理空间上两个进程的数据段和堆栈段都还是共享着的,当有一个进程写了某个数据时,这时两个进程之间的数据才有了区别,系统就将有区别的“页”从物理上也分开。系统在空间上的开销就可以达到最小。
4.1.3 Linux的进程与Win32的进程/线程的区别
UNIX里的fork是七十年代UNIX早期的开发者经过长期在理论和实践上的艰苦探索后取得的成果,一方面, 它使操作系统在进程管理上付出了最小的代价,另一方面,又为程序员提供了一个简洁明了的多进程方法。
WIN32里的进程/线程是继承自OS/2的。在WIN32里,“进程”是指一个程序,而“线程”是一个“进程” 里的一个执行“线索”。从核心上讲,WIN32的多进程与UNIX并无多大的区别,在WIN32里的线程才相当于UNIX 的进程,是一个实际正在执行的代码。但是,WIN32里同一个进程里各个线程之间是共享数据段的。这才是与 UNIX的进程最大的不同[5]。
4.2多线程设计
线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等。一个进程内的所有线程使用同一个地址空间,而这些线程的执行由系统调度程序控制,调度程序决定哪个线程可执行以及什么时候执行线程。线程有优先级别,优先权较低的线程必须等到优先权较高的线程执行完后再执行。在多处理器的机器上,调度程序可将多个线程放到不同的处理器上去运行,这样可使处理器任务平衡,并提高系统的运行效率[6]。
网络应用程序的一般都会或多或少的使用到线程,甚至可以说,一个功能稍微强大的网络应用程序总会在其中开出或多或少的线程,如果应用程序中开出的线程数目大于二个,那么就可以把这个程序称之为多线程应用程序。那么为什么在网络应用程序总会和线程交缠在一起呢?这是因为网络应用程序在执行的时候,会遇到很多意想不到的问题,其中最常见的是网络阻塞和网络等待等[7]。
程序在处理这些问题的时候往往需要花费很多的时间,如果不使用线程则程序在执行时的就会表现出如运行速度慢,执行时间长,容易出现错误、反应迟钝等问题。而如果把这些可能造成大量占用程序执行时间的过程放在线程中处理,就往往能够大大提高应用程序的运行效率和性能和获得更优良的可伸缩性。那么这是否就意味着应该在网络应用程序中广泛的使用线程呢?情况并非如此,线程其实是一把双刃剑[8],如果不分场合,在不需要使用的地方强行使用就可能会产生许多程序垃圾,或者在程序结束后,由于没有能够销毁创建的进程而导致应用程序挂起等问题。
同样的道理,为了提高网络的传输效率,本项目中在对文件进行分块传输的时候,采用的是多线程的形式,每个线程获得要传输的块号,然后读取相应块,发送到终端。实现过程如图4.1:
线程1
Main
函数
创建第一个线程
线程2
线程n
创建第二个线程
创建第n个线程
终端
发送指定的文件块
发送指定的文件块
发送指定的文件块
File
定位写入文件
图4.1 多线程传输
4.3多线程具体实现代码
//创建线程进行分块传输
pthread_t thread_id1,thread_id2;
int ret1,ret2;
ret1=pthread_create(&thread_id1,NULL,(void *) file_thread1,(void *)can);
If(ret1!=0){
printf("Create pthread error!\n");
exit(1);
}
ret2=pthread_create(&thread_id2,NULL,(void *) file_thread2,(void *)can);
if(ret2!=0){
printf("Create pthread error!\n");
exit(1);
}
//文件分块传输线程
void file_thread1(void* info)
{
struct FileSend fs;
//初始化块编号为0
fs.F_blockID=0;
//初始化保留位
fs.F_resume=0;
//获得参数
int* can;
can = (int*)info;
int newfd,file,file1,size;
newfd=can[0];//套接字描述符
file=can[1];//文件描述符
file1=can[2];//文件双线程,设置每个线程所传的块数
size =can[3];
fs.F_dataLen=size;
//strcpy(rfiBlockstate,"0000\0");
printf("rifBlockstate:%s\n",rfiBlockstate);
//定义接收数据缓冲区
char buf[size];
printf("size:%d\n",size);
int k;
//循环读取和发送数据
while(1){
//从文件开始读取
int F_blockID=fs.F_blockID;
if(rfiBlockstate[F_blockID]=='0'){
//获得文件偏移位
off_t offset = F_blockID*(fs.F_dataLen);
//设置文件当前位置
lseek(file,offset,SEEK_SET);
//读取数据
if((k=read(file,fs.F_data,sizeof(fs.F_data)))<=0)
break;
//输出读到的数据
printf("%s\n",fs.F_data);
//设置传输的字节大小
k=k+3;
//发送数据包
write(newfd,&fs,k);
}
//将块编号加1
fs.F_blockID++;
printf("%x\n",fs.F_blockID);
//如果块编号超过本线程要传的块,退出循环
if(fs.F_blockID>=file1)
break;
//清空缓冲区
memcpy((char*)buf,"\0",sizeof(buf));
//清空结构体中数据区
memcpy((char*)fs.F_data,"\0",sizeof(fs.F_data));
}
}
5. 断点续传的基本原理
为了实现断点续传,设计出了本论文的远程升级通信流程和规约,规约中定义了相应的通信格式和方法,利用相应的通信格式,当主站请求文件信息时,如果得到的回答不是全新升级,则得到该文件信息中相应的哪些块没有传过去,并且只发送相应的块,从而实现断点续传的功能。具体原理阐述如下:
5.1 主站请求文件信息
终端返回的格式如表5.1:
表5.1 终端返回文件信息格式
厂商编号
(1BYTE)
厂商功能扩展码
(1BYTE)
操作码
(1BYTE)
会话号
(4BYTE)
文件版本
(1BYTE)
文件大小
(4BYTE)
升级状态
(2BYTE)
已升级的块掩码
(nBYTE)*
操作码:14h
文件版本:需升级的文件最后升级版本,版本表示方式:如果是1.0则表示为10h,1.1表示为11h
文件大小:文件的实际大小,以字节为单位。
升级状态:上次升级结果,分总数,块大小,字节格式如表5.2:
表5.
展开阅读全文