版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
资料管理系统开发文档徐梁2015.4.19Version1.0TOC\o"1-3"\h\u14389资料管理系统开发文档 114580一、需求分析与功能简介 419957二、整体架构 414696三、文件浏览功能实现 526398四、单个文件下载功能实现 832634五、文件夹下载功能实现 1015580六、范围搜索功能实现 1428805(一)范围精确搜索功能实现 1421647(二)范围模糊搜索功能实现 169229七、快速搜索功能实现 166318(一)数据库结构 1620397(二)服务器程序连接数据库 1729049八、客户端监听程序(云同步) 2026477附录1 229337工程的目录结构: 2215818basic.jsp源代码 2414573basic_error.jsp源代码 282291Socketerror.jsp源代码 2820613SocketPro.jsp源代码 297949SocketSuccess.html源代码 297973Success.jsp源代码 302431lib所需要的文件 3016768JQuery+JQueryUI 3120358struts.xml源代码 3229128filesearch.java源代码 356833FileSize.java源代码 3621207ZIP.java源代码 3811250Fast_is_search.java源代码 403434fast_like_search.java源代码 423676normal_is_search.java源代码 446247Normal_like_search.java源代码 477380searchAction.java源代码 503154FileDownloadPackage.java源代码 5523095FolderZIP.java源代码 569045ServerSocketAction.java源代码 5922471SocketAction.java源代码 6121121filedownloadAction.java源代码 64982附录2 663642Information_Port源代码 6719218MainPro源代码 706896Progress.java源代码 712265Server_Port.java源代码 725252UI.java源代码 7526493DiskCode.java源代码 7927160UIDeCode.java源代码 80一、功能简介随着时间的积累,文件资料变得越来越多。在短短3年的时间里文件资料已经增长到了2T并且正在快速增长,查找和管理变得越来越困难。但是传统的FTP软件只拥有简单的查阅和下载功能而且没有搜索功能,已经无法满足大数据条件下的资料管理和快速有效的查找文资料。中队在资料管理方面迫切需要一款能够有效管理大量数据文件资料的软件。首先软件需要完成以下功能:类似于FTP软件的文件浏览浏览功能。资料文件的单个下载。3.资料文件的批量下载。4.文件的精确搜索。5.文件夹的精确搜索。6.文件的模糊搜索。7.文件夹的模糊搜索。8.文件的范围精确搜索。9.文件夹的范围模糊搜索。10.权限控制,根据登录账号的类型,拥有不同的权限。例如超级管理员拥有上传、下载、修改以及后台操作数据库的权限。而普通用户只有下载和查看的权限。二、整体架构程序采用B/S的全局架构,B/S结构即浏览器和服务器结构。它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。B/S结构是WEB兴起后的一种网络结构模式,WEB浏览器是客户端最主要的应用软件。这种模式统一了客户端,将系统功能实现的核心部分集中到服务器上,简化了系统的开发、维护和使用。客户机上只要安装一个浏览器(Browser),如NetscapeNavigator或InternetExplorer,服务器安装Oracle、Sybase、Informix或SQLServer等数据库。浏览器通过WebServer同数据库进行数据交互。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本(TCO)。程序前端采用JSP实现文件夹结构的显示。核心采用Strtus2作为程序核心处理模块。所有JSP网页采用全动态显示技术。JSP在服务器端运行后,动态的生成所需要的HTML5+CSS3标签语言的语句。实现网页标签语句由服务器自动生成。如图1所示。图1架构总体图Struts2是Struts的下一代产品,是在struts1和WebWork的技术基础上进行了合并的全新的Struts2框架。其全新的Struts2的体系结构与Struts1的体系结构差别巨大。Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2可以理解为WebWork的更新产品。虽然从Struts1到Struts2有着太大的变化,但是相对于WebWork,Struts2的变化很小。当Web容器收到请求(HttpServletRequest)它将请求传递给一个标准的的过滤链包括\o""(ActionContextCleanUp)过滤器,然后经过Otherfilters(SiteMesh,etc),接下来需要调用FilterDispatcher核心控制器,然后它调用ActionMapper确定请求哪个Action,ActionMapper返回一个收集Action详细信息的ActionMaping对象。接下来FilterDispatcher将控制权委派给ActionProxy,ActionProxy调用配置管理器(ConfigurationManager)从配置文件中读取配置信息(struts.xml),然后创建ActionInvocation对象,ActionInvocation在调用Action之前会依次的调用所用配置拦截器(InterceptorN)一旦执行结果返回结果字符串ActionInvocation负责查找结果字符串对应的(Result)然后执行这个ResultResult会调用一些模版(JSP)来呈现页面,之后拦截器(InterceptorN)会在被执行(顺序和Action执行之前相反)最后响应(HttpServletResponse)被返回在web.xml中配置的那些过滤器和(核心控制器)(FilterDispatcher)。三、文件浏览功能实现文件浏览功能的实现分为三个步骤:生成后的网页如图2所示:图2网页前端页面页面核心代码如下所示: <% intdl=(int)session.getAttribute("directoryNumber"); for(intj=0;j<dl;j++) { Stringip=request.getLocalAddr(); Stringdname=(String)session.getAttribute("directoryname"+j); Stringdurl=(String)session.getAttribute("directory"+j); Stringdsize=(String)session.getAttribute("directorysize"+j); Stringdirectory="<trclass='li'><tdid='name'><a href='filesearch?url="+durl+"'><imgsrc='imgs/文件夹.png' onclick='submit()'><span>"+dname+"</span></a></td><td>"+dsize+"</td><td><a href='FolderZIP?url="+durl+"&name="+dname+"&IP="+ip+"'><spanid='down'>下载 </span></a></td></tr>"; out.append(directory); out.flush(); } intfl=(int)session.getAttribute("fileNumber"); for(intj=0;j<fl;j++) { Stringfname=(String)session.getAttribute("filename"+j); Stringfurl=(String)session.getAttribute("file"+j); Stringfilesize=(String)session.getAttribute("filesize"+j); Stringfile="<trclass='li'><tdid='name'><a href='filedownload?url="+furl+"&filename="+fname+"'><imgsrc='imgs/文件.png' onclick='submit()'><span>"+fname+"</span></a></td><td>"+filesize+"</td><td><a href='filedownload?url="+furl+"&filename="+fname+"'><spanid='down'>下载 </span></a></td></tr>"; out.append(file); out.flush(); } %>3.用户通过网页点击网页上的文件夹,产生一个请求。服务器获取请求,交给Action类处理。关键代码如下所示:for(inti=0;i<List.length;i++) { if(List[i].isFile()) { System.out.println("文件:"+List[i]); session.put("filesize"+fileNumber, (List[i].length()/1000000)+"Mb"); session.put("file"+fileNumber,List[i].getPath()); session.put("filename"+fileNumber,List[i].getName()); fileNumber++; } } for(inti=0;i<List.length;i++) { if(List[i].isDirectory()) { System.out.println("文件夹:"+List[i]); System.out.println("文件夹名:"+List[i].getName()); session.put("directory"+directoryNumber,List[i].getPath()); session.put("directoryname"+directoryNumber,List[i].getName()); session.put("directorysize"+directoryNumber, (List[i].length()/1000000)+"Mb"); directoryNumber++; } } session.put("fileNumber",fileNumber); session.put("directoryNumber",directoryNumber); returnSUCCESS在文件浏览是,为了防止用户访问服务器的其他区域,需要加一个访问路径的限定,实现代码如下所示: publicStringexecute(){ session.clear(); if(url.indexOf("j:\\file")==-1){//规定文件路径访问范围范围(\\代表\) System.out.println(url.indexOf("j:\\file")); returnERROR;}FileSize.java实现文件的计算,因为文件夹内部有很多个文件,全部计算耗费的运算资源是巨大的。所以只计算单个文件的大小。当文件大小小于1MB时,文件已无大小计算必要,所以不计算大小,与文件夹一样大小显示为0MB。关键代码如下所示:publicvoidgetsize(Filefile){ File[]List=file.listFiles(); System.out.println("该目录下对象个数:"+List.length); for(inti=0;i<List.length;i++){ if(List[i].isFile()){ System.out.println("文件:"+List[i]); num++; size=size+List[i].length()/1000000; if(size>3000||num>15000){//大于2G break; } } if(List[i].isDirectory()){ System.out.println("文件夹:"+List[i]); getsize(List[i]); } }}Strtus2获取文件夹列表后,将文件名、文件路径、文件大小存入session内,然后根据session里内容的不同,在服务器端生成相应的页面代码。返回给用户浏览器,完成一次浏览。如图3所示:图3响应页面四、单个文件下载功能实现单个文件的下载采用Strtus2实现。首先需要配置一个Action的拦截器,拦截filedownlaod请求。打开Strtus.xml配置一个Action,具体代码如下所示:<actionname="filedownload"class="UPDownload.filedownloadAction"><!--下载--> <resultname="success"type="stream"> <paramname="contentType">application/octet-stream</param><!--文件类型 ( 无限制)--> <param name="contentDisposition">attachment;filename="${getName()}"</param><!--使用经过转码的文件名作为下载文件名——默认格式是attachment;filename="${fileName}",将调用该Action中的getFileName方法。--><paramname="inputName">downloadFile</param><!--inputName流对象名——比如这里写inputStream,它就会自动去找Action中的getInputStream方法。--> <paramname="bufferSize">4096</param><!--bufferSize下载文件的缓冲大小--> </result></action>Action拦截到filedownlaod请求后,将请求参数传递给filedownaction处理。其中请求参数filename表示文件的名称,url文件在服务器磁盘的绝对路径。具体代码如下:privateStringfilename; privateStringurl; publicStringgetName(){ byte[]b; try{ System.out.println("filename:"+filename); b=filename.getBytes(); Strings=newString(b,"ISO8859-1"); returns; }catch(UnsupportedEncodingExceptione){ System.out.println("错误!"); e.printStackTrace(); } returnfilename; } publicStringgetFilename(){ returnfilename; } publicvoidsetFilename(Stringfilename){ this.filename=filename; } publicInputStreamgetDownloadFile() { try{ return(newFileInputStream(url)); }catch(FileNotFoundExceptione){ System.out.println("FileNotFound"); e.printStackTrace(); } returnnull; }publicStringexecute(){ returnSUCCESS; }图9实现单个文件下载的Action类当用户点击下载,后会出现如图4所示的下载框。用户可选择文件存储位置以及修改文件名称,点击保存后,开始下载。如图5所示:图4下载框图5文件开始下载五、文件夹下载功能实现文件夹下载采用客户端方式实现,首先介绍服务器端的程序。用户在浏览器上点击下载,然后浏览器产生一个FolderZIP请求。Strtus2拦截到FolderZIP请求后将请求参数文件夹路径url、用户IP、文件夹名称name传递给SocketAction处理。拦截器配置文件如下所示: <actionname="FolderZIP"class="TestSocket.FolderZIP"><!--文件夹 <resultname="success"> /SocketSuccess.html </result> <resultname="error"> /Socketerror.jsp </result> </action>SocketAction在54321号端口建立Socket通信。成功连接客户端后发送通信数据包,通信数据传输、数据包结构如下所示:Socketclient_Inf=newSocket(IP,54321); System.out.println("开始发送通信数据包..."); client_Inf.getOutputStream(); FileDownloadPackagefiledownloadPackage=newFileDownloadPackage(); filedownloadPackage.Header="CreateFolder"; filedownloadPackage.SourseIP=client_Inf.getLocalAddress().getHostAddress(); filedownloadPackage.Port=client_Inf.getLocalPort(); filedownloadPackage.Name=name; filedownloadPackage.Location=""; filedownloadPackage.Blank="123"; ObjectOutputStreamoos=newObjectOutputStream(client_Inf.getOutputStream()); oos.writeObject(filedownloadPackage); System.out.println("发送通信数据包成功..."); oos.flush(); r.delay(1000); oos.close(); client_Inf.close(); r.delay(2000);
/** *文件夹下载数据结构 */ privatestaticfinallongserialVersionUID=1L; publicStringHeader;//文件头CreateDirectorFolder publicStringSourseIP;//发送方IP publicintPort;//发送方端口 publicStringName;//文件夹名称 publicStringLocation;//需要创建的位置,j:/file的后续位置例如Location=/g1 publicStringBlank;//保留位客户端接收到通信数据包后解析,数据包内容,打开59999号端口准备接收文件。在下载之前需要进行文件夹大小计算,如果文件夹总大小大于等于3GB这停止递归调用,返回Size,当文件夹计算函数返回error,提示用户下载文件夹过大,建议分开下载。文件夹大小计算函数如下所示:/** *验证文件夹大小 */ FileSizefs=newFileSize(); fs.getsize(newFile(url)); if(fs.num>10000||fs.size>3000){//文件数目>10000文件大小大于3G System.out.println("文件大小="+fs.size); System.out.println("文件个数="+fs.num); return"error"; }如果计算文件大小小于3GB,服务器调用ZIP类,实现指定文件夹的压缩打包。ZIP类的主要方法为遍历文件夹,将文件夹内的文件依次压缩。ZIP类代码如下:publicclassZIP{ /**创建一个压缩文件,from为文件夹路径,to为创建好后压缩文件路径*/ publicvoidCreateZip(Stringfrom,OutputStreamto)throwsIOException { List<File>list=getFiles(from); ZipOutputStreamout=newZipOutputStream(to); for(Filef:list) { InputStreamin=newFileInputStream(f); Stringname=getRelName(from,f); ZipEntryen=newZipEntry(newFile(from).getName()+"/"+name); en.setSize(f.length()); out.putNextEntry(en); out.setComment("中文测试"); intlen=0; byte[]buffer=newbyte[1024]; while(-1!=(len=in.read(buffer))) { out.write(buffer,0,len); } in.close(); } out.close(); } /**获取文件的相对路径*/ privateStringgetRelName(Stringfrom,Filef){ //TODOAuto-generatedmethodstub Stringa=f.getAbsolutePath().replace(from+"\\",""); a=a.replace("\\","/"); System.out.println(from+""+a); returna; } /**获取路径下所有文件,包括文件夹下的*/ privateList<File>getFiles(Stringsou) { List<File>list=newArrayList<File>(); Filef=newFile(sou); Filefiles[]=f.listFiles(); for(Filefile:files) { if(file.isFile()) { list.add(file); } else { list.addAll(getFiles(file.getPath())); } } returnlist; }}文件成功压缩后存储于服务器的缓存中,服务器调用数据传输端口与客户端的59999号端口建立Socket链接,开始传输缓存里的压缩文件。实现代码如下所示:Socketclient=newSocket(IP,defaultPort); System.out.println("下载链接创建成功!目标IP="+IP+"目标端口="+defaultPort); FileInputStreamfis=newFileInputStream("j:/file/java.zip"); OutputStreamnetOut=client.getOutputStream(); OutputStreamout=newDataOutputStream(newBufferedOutputStream(netOut)); byte[]buffer=newbyte[4096]; intnum=fis.read(buffer); while(num!=(-1)){ out.write(buffer,0,num); out.flush(); num=fis.read(buffer); } out.flush(); out.close(); fis.close(); client.close();客户端程序采用多线程技术,在实现文件夹压缩下载功能时总共使用了3个线程main(String[]args)主线程、Information_Port通信数据端口监视线程、Server_Port数据传输线程、Progress下载进度监视线程。下面我将分别介绍四个线程的作用、代码实现。main(String[]args)主线程为程序主入口,主线程主要作用是创建、开启和关闭其他线程。所有的线程都在主线程里调用。主线程代码如下:publicstaticvoidmain(String[]args)throwsAWTException { UIDeCodeuicode=newUIDeCode(); uicode.lanchframe(); UIui=newUI("59999下载端口监视"); ui.LanchFrame(); Information_Portinfp=newInformation_Port(ui); Threadtinfp=newThread(infp); tinfp.start(); Server_Portsp=newServer_Port(ui,infp); Threadtsp=newThread(sp); tsp.start(); }六、范围搜索功能实现(一)范围精确搜索功能实现范围精确搜索由两个函数实现,分别是search_file()搜索文件和search_d()搜索文件夹。函数的执行步奏主要是:获取前端传来的请求参数,利用Filefile=newFile()创建文件引用,然后利用listFile()函数获取文件列表。然后使用循环语句依次对文件明进行获取。如果文件名与所要搜索的文件名相同,这执行将文件名、文件路径、文件大小存入Session返回前台。如果是文件夹则进行递归调用,即函数自己调用自己。关键代码如图所示: publicvoidsearch_file(Stringurl){ //session.clear(); Filefile=newFile(url);//创建文件 File[]List=file.listFiles();//将文件列表放入List数组 if(List==null){//判断是否为空文件夹或者文件不存在 System.out.println("空文件夹"); System.out.println("RobotchappeComplete!在"); } else{ //System.out.println("该目录下对象个数:"+List.length); for(inti=0;i<List.length;i++) { if(List[i].isFile()) { if(List[i].getName().equals(name)){//比较文件名称与需要查询的名称 System.out.println("找到文件!!!!!!"+List[i].getPath()); Stringp=List[i].getPath();//获取文件路径 Stringname=List[i].getName();//获取文件名称 session.put("file"+k,p);//将文件路径存入Session session.put("filename"+k,name);//将文件名称存入Session session.put("filesize"+k,List[i].length()/1000000+"M"); k++; } } } for(inti=0;i<List.length;i++) { if(List[i].isDirectory()) { search_file(List[i].getPath());//递归调用! } } } session.put("fileNumber",k); }同理文件夹的精确搜索实现代码如下:publicvoidsearch_d(Stringurl){ intk=0; Filefile=newFile(url); File[]List=file.listFiles(); if(List==null){ System.out.println("空文件夹"); System.out.println("RobotchappeComplete!在"); } else{ System.out.println("该目录下对象个数:"+List.length); for(inti=0;i<List.length;i++) { if(List[i].isFile()) { } } for(inti=0;i<List.length;i++) { if(List[i].isDirectory()) { if(List[i].getName().equals(name)){ System.out.println("找到文件夹夹夹!!!!!!"+List[i].getPath()); session.put("directory"+k,List[i].getPath()); session.put("directoryname"+k,List[i].getName()); session.put("directorysize"+k,List[i].length()/1000000+"M"); k++; } search_d(List[i].getPath()); } } } session.put("directoryNumber",k); }}(二)范围模糊搜索功能实现范围模糊搜索功能的实现,与范围精确搜索功能的实现大同小异。唯一的区别在于,文件夹名称的比较。只要文件夹中有搜索的关键字,则认为找到文件或者文件夹。关键代码如下: if(List[i].getName().indexOf(name)!=-1){//查找的字符串在文件名中 System.out.println("找到文件!!!!!!"+List[i].getPath()); Stringp=List[i].getPath(); Stringname=List[i].getName(); session.put("file"+k,p); session.put("filename"+k,name); session.put("filesize"+k,List[i].length()/1000000+"M"); k++; }七、快速搜索功能实现快速搜索采用建立数据库索引的方法。首先服务器运行索引建立程序。按着程序的默认设置,索引每天更新一次,当晚上12点时程序自动运行。50万个文件的索引建立大约需要2小时。数据库结构数据库采用MySQL数据库。MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle公司。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权政策(本词条“授权政策”),它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。数据库名称为qbzdfile用户名:dx密码:1026278249如图6所示:图6数据库整体结构文件和文件夹的Table结构相同,number为一个Int整数型自增主键,number代表文件的唯一编码。name是一个varchar类型代表文件的名称。url是一个varchar类型代表文件在服务器磁盘的绝对路径。size是一个varchar类型代表文件的大小。如图7所示:图7文件和文件夹的Table服务器程序连接数据库实现导入mysql-connector-java-5.1.6-bin.jar文件到lib项目文件夹。利用JDBC技术实现Java服务器与数据库的连接。JDBC(JavaDataBaseConnectivity,java数据库连接)是一种用于执行SQL语句的JavaAPI,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。Java具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。所需要的只是Java应用程序与各种不同数据库之间进行对话的方法。而JDBC正是作为此种用途的机制。JDBC扩展了Java的功能。例如,用Java和JDBCAPI可以发布含有applet的网页,而该applet使用的信息可能来自远程数据库。企业也可以用JDBC通过Intranet将所有职员连到一个或多个内部数据库中(即使这些职员所用的计算机有Windows、Macintosh和UNIX等各种不同的操作系统)。随着越来越多的程序员开始使用Java编程语言,对从Java中便捷地访问数据库的要求也在日益增加。MIS管理员们都喜欢Java和JDBC的结合,因为它使信息传播变得容易和经济。企业可继续使用它们安装好的数据库,并能便捷地存取信息,即使这些信息是储存在不同数据库管理系统上。新程序的开发期很短。安装和版本控制将大为简化。程序员可只编写一遍应用程序或只更新一次,然后将它放到服务器上,随后任何人就都可得到最新版本的应用程序。对于商务上的销售信息服务,Java和JDBC可为外部客户提供获取信息更新的更好方法。快速搜索也分为文件搜索和文件夹搜索。程序执行方式基本与范围搜索相同,只是在数据库的架构下执行。程序关键代码如下:publicvoidsaerch_file(){ try{ Class.forName("org.gjt.mm.mysql.Driver"); Connectionconn=DriverManager.getConnection("jdbc:mysql:" +"//localhost:3306/qbzdfile?user=dx&password=1026278249"); Statementstm=conn.createStatement(); ResultSetrs=stm.executeQuery("select*fromfilewherename='"+name+"'"); while(rs.next()){ Stringname=rs.getString("name"); Stringsize=rs.getString("size"); Stringurl=rs.getString("url"); session.put("filename"+k,name); session.put("filesize"+k,size); session.put("file"+k,url); k++; } }catch(ClassNotFoundException|SQLExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } session.put("fileNumber",k); } publicvoidsaerch_d(){ try{ Class.forName("org.gjt.mm.mysql.Driver"); Connectionconn=DriverManager.getConnection("jdbc:mysql:" +"//localhost:3306/qbzdfile?user=dx&password=1026278249"); Statementstm=conn.createStatement(); ResultSetrs=stm.executeQuery("select*fromdwherename='"+name+"'"); while(rs.next()){ Stringname=rs.getString("name"); Stringsize=rs.getString("size"); Stringurl=rs.getString("url"); session.put("directoryname"+k,name); session.put("directorysize"+k,size); session.put("directory"+k,url); k++; } }catch(ClassNotFoundException|SQLExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } session.put("directoryNumber",k); }
八、客户端监听程序(云同步)客户端采用Socket编程,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。Socket的英文原义是“孔”或“插座”。作为BSDUNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。正如打电话之前,双方必须各自拥有一台电话机一样。在网间网内部,每一个Socket用一个半相关描述:(协议,本地地址,本地端口)。一个完整的Socket有一个本地唯一的Socket号,由操作系统分配。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。在本程序中,开发者定义59999号端口为下载端口,54321号端口为通信数据传输端口。两个端口都设置多线程监视。采用多线程可以提高CPU的运算效率,同时也能防止主线程的阻塞。客户端程序总共用4个线程,第一个是主线程MainPro,第二个线程是54321号端口监视线程Information_Port,第三个线程是59999号端口监视线程Server_Port,第四个线程是下载进度监视线程Progress。客户端具体实现的功能就是接受服务器发送的数据包。然后对数据包进行解析。如果为通信数据包则获取数据包信息,如果为下载数据包则将数据保存至用户选择的地方。代码详见附录2。
附录1工程的目录结构:
basic.jsp源代码<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%@tagliburi="/struts-tags"prefix="s"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""/TR/html4/loose.dtd"><html><head><metahttp-equiv="Content-Type"content="text/html;charset=UTF-8"><title>文件浏览动态生成页面</title> <scriptsrc="JQuery+UI/jquery-2.1.3.min.js"></script><scriptsrc="JQuery+UI/jquery-ui.min.js"></script><linktype="text/css"rel="stylesheet"href="JQuery+UI/jquery-ui.min.css"><styletype="text/css"> img{ width:20px; height:20px; } a{ text-decoration:none; color:black; } a:VISITED{ color:black; } #li_header{background-color:#585fff;width:100%;font-size:20px;color:#ffffff;}.header_p{color:#ffffff;font-size:20px;text-align:center;}#name{ text-align:left;}.selectmenu{ width:104px; height:30px; font-size:16px;}#down{ color:blue;}.li{ background-color:#F3F3F3; font-size:15px;}.li:HOVER{ background-color:#c8ceff;}</style></head><bodystyle="width:1200px;margin:0pxauto;"> <divid="w1000"style="width:1000px;margin:5pxauto;"> <formaction="filesearch"method="get"> <imgsrc="imgs/主页.jpg"onclick="submit()"> <inputtype="text"name="url"value="j:\file"style="display:none;"> </form> <formaction="filesearch"method="get"> <inputid="url"type="text"name="url"value="<%=session.getAttribute("path")%>"style="font-size:20px;width:950px;height:25px;margin-bottom:5px;"> <aid="tiao"href="#"><imgsrc="imgs/跳转到.png"style="margin-top:5px;"> </a> <script> setInterval(functiondx(){ varu=document.getElementById("url").value; //alert(u); document.getElementById("tiao").href="filesearch?url="+u; },300) </script> </form> <formaction="search"target="_blank"> <selectclass="selectmenu"name="method"><optionvalue="fast">快速搜索</option><optionvalue="normal">全面搜索</option></select> <selectclass="selectmenu"name="type"> <optionvalue="like">模糊搜索</option><optionvalue="is">精确搜索</option></select> <selectclass="selectmenu"name="search_value"> <optionvalue="f">文件</option><optionvalue="d">文件夹</option></select> <inputstyle="width:550px;height:30px;font-size:16px;"type="search"name="name"value=""> <inputclass="selectmenu"type="submit"value="搜索"> <inputstyle="display:none;"type="text"name="url"value="<%=session.getAttribute("path")%>"> </form> <divstyle="text-align:center;"> <tablestyle="width:100%"><trid='li_header'><tdclass='header_p'>名称</td><tdclass
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 光学仪器在冶金工程中的应用考核试卷
- 宠物脱毛疗法减轻宠物过敏和脱毛问题考核试卷
- 创业者的团队激励与绩效评估考核试卷
- 企业危机管理与业务恢复计划策略考核试卷
- 南京信息工程大学《向量微积分》2023-2024学年第一学期期末试卷
- 放射性金属矿的矿产资源开发与保护考核试卷
- 制造业绿色转型可持续生产的实践考核试卷
- 《美好生活视域下大学生劳动观教育研究》
- 信息系统开发流程控制考核试卷
- 危险品仓储集装箱安全管理考核试卷
- GB∕T 1927.9-2021 无疵小试样木材物理力学性质试验方法 第9部分:抗弯强度测定
- 三年泡胖大海
- 《七律长征》教案
- 三年发展规划表
- 公司会议签到表模板
- 美术五年级上册人美版 第15课 造型别致的椅子(课件)(11张PPT)
- 部编版语文三年级上册单元知识点梳理归纳
- TS16949推行计划
- 2009年勒流街道小学即席作文竞赛获奖结果(精)
- 三年级地方课程半岛工程和温州大桥教材
- 人民医院便民惠民措施服务工作开展情况总结
评论
0/150
提交评论