




已阅读5页,还剩63页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
辽宁工程技术大学毕业设计(论文)摘要随着时代的发展,人们互相交流的方式也在逐渐变化,从原来的面对面,到电话、手机,然后到短信、E-mail,再到现在的QQ、微信,聊天变得越来越具有实时性和有效性。但是现在聊天软件都必须连接到Internet后才能够让人们相互交流。如果用户在工作时候连接网络,有可能因为网络的关系使得工作效率变低;也有可能因为网络的关系,让公司内部的资料被泄露出去,使公司收到损失。因此进行一个在局域网下的聊天工具的设计是很有必要的。本文介绍了在局域网内实现相互收发消息的基本流程,并且编写了一个基于Socket的聊天窗口。这个简单的软件采用的是C/S结构模式,即客户端/服务器模式。这个软件可以让客户端和客户端能够进行通信,服务器端也能够对客户端进行发消息,还能够进行监听客户端的所有消息。不足之处是只能够启动一个服务器,所有的客户端只能够通过一个端口连接服务器进行通信。如果让客户端不看到不属于这个端口的其它客户发的消息,必须重新定义Server端,更改端口。本文用到了Sock编程、多线程、TCP/IP协议还有图形界面设计的控件编程的知识。通过对程序进行测试,发现程序能够在同一个局域网下实现多人通信。我们也许通过路由器分配的IP,也可以利用现在流行的“免费WiFi”,让所有人连接WiFi,这样,也会给每个客户端分配IP地址,这样也就有了局域网,它并不需要外网的帮助。关键词:局域网;Socket;多线程;TCP/IP AbstractWith the development of the times, the communication mode of people is changed gradually. Yesterday, we communicated with each other face to face, then we tell something to others using telephone, cellphone, and then using message, e-mail. Now we tell something to each other with QQ, MSN and wechat. Communication becomes more and more real-time and ephemeral. But the software we used should depend on the Internet. If not, they are nothing. If we connect the Internent during working, we may not devote ourself into our jobs. And also, the important information may be leaked to let the company lost money. So it is important to design a software about chating in the LAN but not on the Internet.This paper intruduce that people send messages to each other in the local area network. And Programming the chat window based on the Socket. This simple application use the C/S model. The C/S model is Client/Server model. This application can let the different client sends or receives messages. Server can send message to every client and it can get all messages of every client sends. There is a weak point that people can just start one server. All clients should use the port the server given. If we want to divide people, we should change the port and copy another “Server” code to start new server, then some people use this server and others use another server. This paper uses the knowledges about the Socket programming, multithreading, TCP/IP protocol and the control programming about the GUI.When tested, the application can let multi clients send or receive messages. We may use the IP that the router gives us, we can also use the “Free-WiFi” that is popular now to let everyone connect the WiFi, then everybody has one IP. People have a local area network and it does not need the Internet.Key words: Local Area Network; Socket; Multithreading; TCP/IP I目录引言11 实现原理21.1 C/S结构21.2 TCP/IP协议41.3 套接字51.4 多线程61.5 Socket的同步和异步方式81.6 用Socket开发的C/S模型82 总体设计92.1 程序实现原理92.2 C/S架构设计102.3 数据流图113 模块设计123.1 系统的总体流程图123.3 上传文件143.4 下载文件153.5 服务器和客户端图形界面的的详细设计173.6 服务器等待连接的详细设计203.7 监听端的详细设计213.8 客户端发送消息内容以及连接服务器程序223.6 获得客户端ip224 系统测试234.1 聊天程序测试234.2 上传与下载程序测试26致谢28参考文献29附录A30 附录B43引言近年来,随着科技的不断进步,网络也在快速向前发展着。企业为了高效迅速并且安全地处理各种事情,它们越来越多地使用局域网来工作而不用外部网路。因为局域网能够提高信息传输效率,简化信息的传递途径,这样便能够提高工作效率。还有一个原因是使用Internet传递信息,这些信息有可能会泄露出去,对企业产生危害。基于这种情况,局域网聊天工具就出现了。本文的通信程序设计采用的是基于Socket的局域网通信工具的设计。如果通信软件是基于Socket的,那么它可以利用局域网传递信息,给企业提供高效率、安全的通信机制。还有一个优点是,使用基于Socket的软件可以不需要对企业原有的网络进行改动,因此不需要什么实现的成本1。Socket其实不仅能够用于传递文字信息,还能够传输文件,这样的话,它也就可以对视频、音频进行传输。因此它的应用范围就不会那么局限了。这也是它能够让大众接受的原因之一。当下有很多聊天软件,例如腾讯QQ、微信、MSN。QQ在前几年到现在都是很受欢迎的软件,基本每个人都会有至少一个QQ账号。在此,就选取它来进行大体研究,看看它是如何实现单人和单人以及在组群中聊天的。通过网络上的信息,可以了解到QQ是以多服务器提供服务、服务器总控客户端、客户端之间UDP直接通信的,并且仅仅是在两个客户端之间没有建立过连接时候,才会利用服务器对客户端的信息进行转发。在这种模式下,服务器主要是用来处理客户端各种状态的控制,这么做能够很大程度上减少服务器的工作量。但是这里面的实现是比较复杂的。此次课程设计完成了一个Server可以让多个Client和它建立链接并且相互发送信息的程序,并不需要那么复杂,因此还是利用了这种C/S结构。1 实现原理本次通信程序的实现用的是Java语言。Java是一种可以编写跨平台应用软件的面向对象的程序设计语言,网络应用是Java语言取得成功的领域之一,它己经成为现在Internet上最流行的一种编程语言。网络编程的目的就是直接或间接地通过网络协议与其它计算机进行通讯。两台计算机通讯需解决两个主要问题:一是如何准确定位网络上的主机;二是找到主机后如何可靠有效地进行数据传输。2Java语言作为网络编程语言,提供了强大的网络编程接口。针对网络通信的不同层次,Java提供的网络功能的类有四种,它们分别是InetAddress、URL、Socket和Datagramo。Socket是Internet使用的协议组TCP/IP的组合,实现了两台主机之间通过端口进行网络通信。J包中提供Socket类,隐藏了Socket的实现细节,不需要开发者编写接口程序,而可以快速的实现网络的通信。31.1 C/S结构Client/Server结构(C/S结构)是大家熟知的客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。当下的很多软件都是基于Client/Server形式的两层结构,这是因为现在的软件和应用系统都在想着分布式的Web应用发展,而C/S结构对此很有优势。举个例子,大家都只到QQ,那么也应该知道WebQQ。如果QQ需要更新,那么我们每个客户端都需要进行接入网络然后进行更新,才可以享用新版本,但是WebQQ只需要服务器端进行更新即可,根本不需要使用者做更新的操作。专业地来讲,Web和Client/Server应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向。C/S结构的优点是能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再提交给服务器。对应的优点就是客户端响应速度快。缺点主要有以下几个:(1)只适用于局域网。而随着互联网的飞速发展,移动办公和分布式办公越来越普及,这需要我们的系统具有扩展性。这种方式远程访问需要专门的技术,同时要对系统进行专门的设计来处理分布式的数据。(2)客户端需要安装专用的客户端软件。首先涉及到安装的工作量,其次任何一台电脑出问题,如病毒、硬件损坏,都需要进行安装或维护。还有,系统软件升级时,每一台客户机需要重新安装,其维护和升级成本非常高。(3)对客户端的操作系统一般也会有限制。可能适应于Win2000或WindowsXP,但不能用于Windows7。或者不适用于微软新的操作系统等等,更不用说Linux、Unix等。4 C/S架构软件的优势与劣势:(1)应用服务器运行数据负荷较轻。最简单的C/S体系结构的数据库应用由两部分组成,即客户应用程序和数据库服务器程序。二者可分别称为前台程序与后台程序。运行数据库服务器程序的机器,也称为应用服务器。一旦服务器程序被启动,就随时等待响应客户程序发来的请求;客户应用程序运行在用户自己的电脑上,对应于数据库服务器,可称为客户电脑,当需要对数据库中的数据进行任何操作时,客户程序就自动地寻找服务器程序,并向其发出请求,服务器程序根据预定的规则作出应答,送回结果,应用服务器运行数据负荷较轻。(2)数据的储存管理功能较为透明。在数据库应用中,数据的储存管理功能,是由服务器程序和客户应用程序分别独立进行的,前台应用可以违反的规则,并且通常把那些不同的(不管是已知还是未知的)运行数据,在服务器程序中不集中实现,例如访问者的权限,编号可以重复、必须有客户才能建立定单这样的规则。所有这些,对于工作在前台程序上的最终用户,是“透明”的,他们无须过问(通常也无法干涉)背后的过程,就可以完成自己的一切工作。在客户服务器架构的应用中,前台程序不是非常“瘦小”,麻烦的事情都交给了服务器和网络。在C/S体系的下,数据库不能真正成为公共、专业化的仓库,它受到独立的专门管理。(3)C/S架构的劣势是高昂的维护成本且投资大。首先,采用C/S架构,要选择适当的数据库平台来实现数据库数据的真正“统一”,使分布于两地的数据同步完全交由数据库系统去管理,但逻辑上两地的操作者要直接访问同一个数据库才能有效实现,有这样一些问题,如果需要建立“实时”的数据同步,就必须在两地间建立实时的通讯连接,保持两地的数据库服务器在线运行,网络管理工作人员既要对服务器维护管理,又要对客户端维护和管理,这需要高昂的投资和复杂的技术支持,维护成本很高,维护任务量大。其次,传统的C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,由于产品的更新换代十分快,代价高和低效率已经不适应工作需要5。1.2 TCP/IP协议网际协议IP是TCP/IP的心脏,也是网络层中最重要的协议。IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层-TCP(The Transmission Control Protocol)或UDP(User Datagram Protocol)层;相反,IP层也把从TCP或UDP层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是否按顺序发送的或者被破坏。IP数据包中含有发送它的主机地址(源地址)和接收它的主机的地址(目的地址)。如果IP数据包中有已经封好的TCP数据包,那么IP将把他们向上传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。UDP与TCP位于同一层,但对于数据包的顺序错误或重发。因此,UDP不被应用于那些使用虚电路的面向连接的服务UDP主要用于那些面向查询应答的服务。TCP和UDP服务通常有一个客户/服务器的关系6。端口被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,例如,SMTP使用25。这些端口号是“广为人知”的,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通讯。程序中,下载文件的程序设计用的是UDP协议,因此有时候会传输失败,这是有原因的。(1)发送频率过高导致丢包。很多人会不理解发送速度过快为什么会产生丢包,原因就是UDP的SendTo不会造成线程阻塞,也就是说,UDP的SentTo不会像TCP中的SendTo那样,直到数据完全发送才会return回调用函数,它不保证当执行下一条语句时数据是否被发送。(SendTo方法是异步的)这样,如果要发送的数据过多或者过大,那么在缓冲区满的那个瞬间要发送的报文就很有可能被丢失。至于对“过快”的解释,作者这样说:“A few packets a second are not an issue; hundreds or thousands may be an issue.”(一秒钟几个数据包不算什么,但是一秒钟成百上千的数据包就不好办了)。 (2)报文过大丢包。至于报文过大的问题,可以通过控制报文大小来解决,使得每个报文的长度小于MTU。以太网的MTU通常是1500 bytes,其他一些诸如拨号连接的网络MTU值为1280 bytes,如果使用speaking这样很难得到MTU的网络,那么最好将报文长度控制在1280 bytes以下。(3)发送方丢包。发送方丢包:内部缓冲区(internal buffers)已满,并且发送速度过快(即发送两个报文之间的间隔过短);接收方丢包:Socket未开始监听;虽然UDP的报文长度最大可以达到64 kb,但是当报文过大时,稳定性会大大减弱。这是因为当报文过大时会被分割,使得每个分割块(翻译可能有误差,原文是fragmentation)的长度小于MTU,然后分别发送,并在接收方重新组合(reassemble),但是如果其中一个报文丢失,那么其他已收到的报文都无法返回给程序,也就无法得到完整的数据了7。1.3 套接字套接字(Socket)是通信的基础,它是支持TCP/IP协议的网络通信基本单元。我们可以将套接字看作为不同的主机进行双向通信的端点,它让主机间产生了联系。套接字存在于通信域里。通信域通常和与它在同一个域里的套接字交换数据。各种进程利用相同的域通过Internet协议簇进行通信。套接字可以根据通信性质分类,这种性质对于用户是可见的。应用程序一般仅在同一类的套接字间进行通信。不过只要底层的通信协议允许,不同类型的套接字间也照样可以通信8。套接字有三种不同的类型:流套接字、数据报套接字和原始套接字。流套接字(SOCK_STREAM):流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP协议。数据报套接字(SOCK_DGRAM):数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议进行数据的传输。由于数据包套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。原始套接字(SOCK_RAW)与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。9因此,如果要访问其他协议发送数据必须使用原始套接字。套接字的工作原理可以简单描述:要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户机端,我们称之为ClientSocket,另一个运行于服务器端,我们称之为ServerSocket。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。所谓服务器监听,是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。所谓客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其它客户端套接字的连接请求10。1.4 多线程CPU生产商为了提高CPU的性能,通常做法是提高CPU的时钟频率和增加缓存容量。不过目前CPU的频率越来越快,如果再通过提升CPU频率和增加缓存的方法来提高性能,往往会受到制造工艺上的限制以及成本过高的制约。尽管提高CPU的时钟频率和增加缓存容量后的确可以改善性能,但这样的CPU性能提高在技术上存在较大的难度。实际上在应用中基于很多原因,CPU的执行单元都没有被充分使用。如果CPU不能正常读取数据(总线/内存的瓶颈),其执行单元利用率会明显下降。另外就是目前大多数执行线程缺乏ILP(Instruction-Level-Parallelism,多种指令同时执行)支持。11这些都造成了目前CPU的性能没有得到全部的发挥。因此,Intel则采用另一个思路去提高CPU的性能,让CPU可以同时执行多重线程,就能够让CPU发挥更大效率,即所谓“超线程”(Hyper-Threading,简称“HT”)技术。超线程技术就是利用特殊的硬件指令,把两个逻辑内核模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行效率。采用超线程即是可在同一时间里,应用程序可以使用芯片的不同部分。虽然单线程芯片每秒钟能够处理成千上万条指令,但是在任一时刻只能够对一条指令进行操作。而超线程技术可以使芯片同时进行多线程处理,使芯片性能得到提升。超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在同一时间执行两个线程,P4处理器需要多加入一个Logical CPU Pointer(逻辑处理单元)。因此新一代的P4HT的die的面积比以往的P4增大了5%。而其余部分如ALU(整数运算单元)、FPU(浮点运算单元)、L2Cache(二级缓存)则保持不变,这些部分是被分享的。虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每个CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。英特尔P4超线程有两个运行模式,Single Task Mode(单任务模式)及Multi Task Mode(多任务模式),当程序不支持Multi-Processing(多处理器作业)时,系统会停止其中一个逻辑CPU的运行,把资源集中于单个逻辑CPU中,让单线程程序不会因其中一个逻辑CPU闲置而减低性能,但由于被停止运行的逻辑CPU还是会等待工作,占用一定的资源,因此Hyper-ThreadingCPU运行Single Task Mode程序模式时,有可能达不到不带超线程功能的CPU性能,但性能差距不会太大。也就是说,当运行单线程运用软件时,超线程技术甚至会降低系统性能,尤其在多线程操作系统运行单线程软件时容易出现此问题。12在计算机编程中,一个基本的概念就是同时对多个任务加以控制。许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程。可以通过多种途径达到这个目的。最开始的时候,那些掌握机器低级语言的程序员编写一些“中断服务例程”,主进程的暂停是通过硬件级的中断实现的。尽管这是一种有用的方法,但编出的程序很难移植,由此造成了另一类的代价高昂问题。中断对那些实时性很强的任务来说是很有必要的。但对于其他许多问题,只要求将问题划分进入独立运行的程序片断中,使整个程序能更迅速地响应用户的请求。多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。多线程在构建大型系统的时候是需要重点关注的一个重要方面,特别是在效率(系统跑得多快)和性能(系统工作正常)之间做一个权衡的时候。恰当的使用多线程可以极大的提高系统性能。使用多线程的好处有以下几点:使用线程可以把占据长时间的程序中的任务放到后台去处理;用户界面可以更加吸引人,这样比如用户在点击了一个按钮去触发某些时间的处理,可以弹出一个进度条显示处理的进度;程序的运行速度可能加快;在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了,在这种情况下我们可以释放一些珍贵的资源如内存占用等12。1.5 Socket的同步和异步方式所谓Socket通常也称作套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别13。Socket的同步方式,就是发送方发送数据包以后,不等待接收方响应,就接着发送下一个数据包。Socket的异步方式,就是当发送方发送一个数据包以后,一直等到接收方响应后,才接着发送下一个数据包。关于套接字还有阻塞和非阻塞之分:阻塞套接字是指执行此套接字的网络调用时,直到调用成功才返回,否则此套接字就一直阻塞在网络调用上。而非阻塞套接字是指在执行此套接字的网络调用时,不管成功与否,都立即返回。1.6 用Socket开发的C/S模型开发原理:服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口,这里我的程序使用的是1228端口进行通信),等待客户连接请求,客户连接后,会话产生;在退出客户端后,关闭连接。客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,连接成功;客户端退出后,关闭Socket。客户端在实现文件的上传或者下载的时候,用的分别是1230和9000端口。然后运用文件输入输出流将文件进行上传和下载。一般来说,客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的14。而我设计的软件运用的端口号已经在代码中进行了指定,如果要修改,也只能够在代码中重新指定,并不具备自动分配的功能,这样使得程序十分不灵活,是个比较大的缺点。2 总体设计2.1 程序实现原理聊天系统的设计跟普通网站设计有着许多不同的地方,普通网站设计所考虑的有布局进入大量美化以及动画设计等等,而聊天室只要提供满足访客双方直接实时聊天即可。因此,在设计聊天系统的过程中,重点是从局域网下实现聊天功能。在Internet上的聊天程序一般都是以服务器提供服务端连接响应,使用者通过客户端程序登录到服务器,就可以与登录在同一服务器上的用户交谈,这是一个面向连接的通信过程。因此,在局域网下面,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序。程序的总体框架如图2-1所示。图2-1程序的总体框架Fig.2-1 The general framework of the program2.2 C/S架构设计在设计的程序中,客户端需要将用户的输入消息发送到服务器,然后经由服务器转发到其它的连接到这个服务器(也就是某个端口)上的客户端。那么,可以建立一个线程用来等待客户端的连接,同样建立一个新的线程,在客户端连接后,客户端经由服务器发消息时,服务器可以再服务器窗口打印出消息内容,并且将消息转发出去,实现监听和转发功能。因此在客户端要实现发送消息的方法和在客户端打印将要转发消息的方法。在设计客户端连接这个线程的时候,出现了这个问题。启动Server后,Client连接到服务器,等到退出服务器后,服务器出现异常。这个情况是很严重的。服务器不应该会因为客户端的举动让自己发生错误,服务器应当在启动后一直等待客户端的连接,即使没有客户端连接它,它也应当一直等待着。因此应当在Server程序中写一个死循环来让它一直等待,只要服务器不关闭,如果有客户端连接,就能够让它连接。在这个模块里,顺便实现了在服务器端进行消息的监听,只需要一个打印的方法,将发送过来的消息打印到服务器面板上即可。另外一个线程在程序中用ListenerClient类来实现。用它来对所有其它的连接客户端的用户广播信息。在这个过程中,只需要将接收到的消息再发送出去即可,并不复杂。在设计客户端的时候,也用到了两个线程,一个是从客户端发送消息,另一个则是从服务器接收消息。将不同的功能分配到不同的线程中去,这样可以让程序相应更快,让CPU资源利用率更高。当执行单线程程序时,由于在程序发生阻塞时CPU可能会处于空闲状态。这将造成大量的计算资源的浪费。而在程序中使用多线程可以在某一个线程处于休眠或阻塞时,而CPU又恰好处于空闲状态时来运行其他的线程。这样CPU就很难有空闲的时候。因此,CPU资源就得到了充分地利用。还有一个优势是能够简化异步事件的处理。当执行单线程程序时,由于在程序发生阻塞时CPU可能会处于空闲状态。这将造成大量的计算资源的浪费。而在程序中使用多线程可以在某一个线程处于休眠或阻塞时,而CPU又恰好处于空闲状态时来运行其他的线程。这样CPU就很难有空闲的时候。因此,CPU资源就得到了充分地利用。2.3 数据流图程序的顶层数据流图如图2-2所示。图2-2顶层数据流图Fig.2-2 The top-level of the data flow chart需要进行交流的用户通过局域网聊天系统进行信息的相互传递,不用经过Internet,保证了安全。聊天系统内部数据流图如图2-3所示。图2-3聊天系统内部数据流图Fig.2-3 Chat system internal data flow chart服务器能够处理用户发出的消息,也能够将消息发送到目标用户,服务器还能够对用户的聊天内容进行监控。3 模块设计3.1 系统的总体流程图系统的总体流程图如图3-1所示。首先启动服务器,查看服务器是否启动。如果启动,提供端口等待客户端的连入。启动客户端后,我们连接服务器,之后 可以进行聊天、文件的上传和下载。文件上传与下载之后,退出窗口,仍能够进行相互间的聊天。在关闭窗口的时候,只要关闭服务器端窗口和客户端窗口就可以了。图3-1系统的总体流程图Fig.3-1 The ovarall flow chart of the system在编写程序的时候,将程序分为聊天、上传和下载三个部分。首先分别完成三个部分的功能,然后在界面上添加按钮,通过点击按钮,让三者产生联系。这样就完成了在客户端能够实现聊天、上传文件和下载文件的功能。具体实现,接下来进行说明。3.3 上传文件文件上传流程图如图3-2所示。图3-2 文件上传流程图Fig.3-2 The flow chart of the upload files 当打开客户端,连接服务器之后,我们可以进行文件上传操作。点击上传文件按钮,会弹出上传上传服务器和上传客户端两个窗口。在上传服务器窗口点击“启动服务”按钮,然后在上传客户端点击测试网络按钮。如果弹出“连接失败”的话,就要更改端口号然后再进行测试。当弹出“连接成功”后,就可以点击“浏览”,从而进行本地文件的选定然后进行上传。上传完毕后,就可以关闭这些窗口,停留在最初的聊天窗口,仍然可以进行聊天。注意,这里的端口号要和聊天服务器的端口号保持一致,这样的话,一般客户端能成功连接服务器,那么一定可以进行上传文件的操作。测试网络连接成功后,就可以点击浏览或者输入绝对路径,来选定将要上传的文件。然后点击上传,这样就将文件上传到了服务器。 在程序中,上传服务器是UploadServer类。这里面利用while(true)循环,内部写上socket=server.accept()来保证上传能够一直等待,不会因为一个人断开连接后,就将端口关闭。DataInputStream和BufferedOutputStream是输入输出流,我们可以用它来进行文件的上传下载操作15。 在UploadServer类中,通过bufIn.read(Name)来读取文件的名字,这样将文件上传到服务器后,也能够使用这个名字。通过BufferedOutputStream bufOutFile = new BufferedOutputStream(new FileOutputStream(文件位置 + fileName);我们可以将上传的文件保存在服务器的某个位置。这里我写的是E:/workspace/of Graduation/src/share/。这样就可以在服务器端查看保存的文件了。对于文件内容的传送,首先去判断bufIn.read(bytes)的内容和-1的关系。如果不为-1,说明文件还在传输中,如果是-1,说明文件已经传输完毕,这时候就能够将之前声明的输入输出流对象进行关闭。虽然不进行关闭也可以,但是会浪费资源,不建议这样做。文件的传输利用了bufOutFile.write(bytes,0,line);bufOutFile.flush();这两条语句。程序每次读取1024字节的内容,然后看line的数值。如果不为-1,说明文件没有上传完毕,利用bufOutFile.write(bytes,0,line)每次读取0line的长度,fush()方法则是为了清空缓存。每次读取文件后都清空缓存,知道文件读取完毕。在单独设计上传文件部分时候,在main方法中新建一个UploadServer对象,运行即可进行验证。在全部设计完毕后,除了需要运行的服务器窗口和客户端窗口外,都不需要main方法的。下载客户端写在UploadClient类中。仍然利用DataOutputStream和BufferedInputStream两个类来进行文件的传输。和服务器相同,每次读取1024字节的数据,知道读取完毕。这里的DataOutputStream bufOut 与BufferedInputStream bufIn是相互对应的。如果我们在上传完毕文件后立即关闭客户端,服务器会报错。客户端没有收到流发送完毕的通知,一直在等待,等待的时候服务端异常退出。所以我们要在下面加上一条判断语句,if(!new String(b).trim().equals(“”),当它判断为真后,显示上传成功,然后再关闭连接。这样服务器端口就不会产生错误。 3.4 下载文件下载文件流程图如图3-3所示。图 3-3 下载文件流程图Fig.3-3 The flow chart of download files当打开聊天客户端时候,点击上传文件,点击按钮的同时,就会启动下载服务,然后点击显示文件,能够看到服务器中存储的所有上传文件,然后输入文件名,点击下载,选取本地路径,就能够将文件进行下载到本地。在下载文件这里,利用了UDP协议。UDP协议来传送数据有一定概率使得包变得不完整,这是一个缺陷。下载服务器写在DownloadServer类中。我们仍然利用聊天服务器提供的端口进行文件的下载。程序中,我定义了一个线程池,ExecutorService ThreadPool = Executor.newFixedThreadPool(10),这样最多可以同时开启10个线程进行下载操作,也就是说最多能够让10个客户端同时进行文件的下载操作。利用ThreadPool.execute(new WorkThread(dataPacket)为客户端开一个线程用来下载文件。WorkThread通过继承Runnable,使得WorkThread可以为多个客户端提供下载。利用showFiles()方法来获得客户端的文件名。这里必须先在代码中设置服务器中共享文件的存放路径,然后才能够进行后续操作。通过for(File f:allFile)if(f.is File()message.append(f.getName() message.append(n)遍历文件夹中的每个对象,如果是文件,将文件名和换行进行拼接,然后用来发送给客户端显示所有文件名。利用DatagramPacket来进行文件的发送。在用FileInputStream中的read方法传送数据是写在while死循环中的。通过FileInputStream的available方法,获取传送的数据的大小。如果为0,那么就可以跳出循环,表示数据已经传输完毕。下载窗口写在DownloadClient类中。这里对下载的窗口进行了界面上的设计,这里暂时不考虑它,只说明完成下载功能的部分。我们通过对按钮进行注册事件,能够通过点击来完成按钮对应的功能。在showFiles()方法中,通过String str=new String(receiverPacket.getData(),0,receivePaket.getLength()语句来将服务器的所有文件名赋值给字符串str,然后在界面的textArea中setText(str)将文件名打印出来。在将要下载文件的时候,通过if(fileName = = null | “”.equals(fileName)判断来表明没有输入文件名或者文件名为空的情况,并且出现提示语:请选中正确的文件名或者文件名错误。如果输入的文件名无误,进行下一步操作。选中存在的文件之后,可以用OutputStream的write方法将数据写入此数据输出流中。而数据的来源则是利用receivePacket.getData()方法找到服务器中的文件从而进行数据的传递。3.5 服务器和客户端图形界面的的详细设计Java的GUI程序是以Jframe为基础的,它是屏幕上windows的对象,能够进行最大化、最小化、移动和关闭的操作。Swing的三个基本构造块是标签、按钮和文本字段,但是它们不能够独立存在,要找个地方安置它们。Jframe就是起了这样一个作用。这类似于网页设计中的frameset。网页中可以利用frameset进行基本布局,将网页分为几块,每一块作为一个网页单元,再进行基础的功能设计。服务器与客户端的图形界面如图3-4所示。图3-4服务器与客户端的图形界面Fig.3-4 The graphics interface of the client and server自己设计了简单的服务器端和客户端的图形界面。服务器端有“发送信息”和“启动服务的按钮。客户端只有单击启动服务按钮之后,客户端才能够进行连接。有显示文本的文本框,面积比较大。有输入消息的文本框,在发送消息按钮的旁边,再旁边便是“上传文件”和“下载文件”按钮。服务器端的界面与客户端的界面基本相同。客户端启动连接后,如果服务器没有启动,会显示“连接服务器失败:端口xxxx”的字样;如果服务器启动,那么客户端启动连接后会显示“连接服务器成功:端口xxxx”的字样。如果服务器启动成功,便会出现“启动服务器成功:端口xxxx”的字样。如果有客户端连入,就会出现连接成功的字样。服务器端用客户端的ip地址,port以及localport来唯一地确定一个客户端。服务器的各种状态如图3-5所示。图3-5服务器的各种状态Fig.3-5 All kinds of forms of the server服务器界面设计写在ServerUI类中。界面设计的时候,利用JButton定义两个按钮,作为启动服务器和发送信息。再用JTextArea定义发送消息的框和信息展示框。在启动服务按钮上设定一个监听,当点击按钮,就启动了服务。在发送按钮上设定一个监听,用来获取客户端发送来的消息。再添加一个窗口监听,用来关闭窗口,这里用System.exit(0)来实现程序的完全关闭。最后对文本框和按钮进行布局,让它变得美观。客户端界面设计写在ClientUI类中。这里除了在该界面进行操作外,也要连接到之前讲到过的上传和下载页面。仍然是通过Jbutton和JtextArea来展示按钮和文本框。JtextField则是定义单行输入文本框,用来显示文件与IP地址。我们在启动连接处添加按钮监听,用来让客户端连入服务器。在发送消息按钮上添加监听,我们将消息发送出去。在下载文件按钮处添加监听,这里链接到DownloadClient类中,打开下载窗口。如图3-6所示。此窗口在类DownloadClient中进行设计。同样在显示文件这个按钮上创建监听,调用showFiles()方法,将文件展示在文本窗口,点击下载按钮,在监听中实现文件的下载。图 3-6 下载窗口Fig.3-6 The window of download在上传文件的按钮上实现监听。从而将程序跳转到自己所写的上传JAVA包中的文件。通过点击文件上传按钮,让UploadClient和UploadServer同时启动,由于已经启用1228端口(本次测试将要使用的用来聊天的端口),所以直接点击“测试网络”按钮,如果显示连接成功,则服务器自动给上传服务分配一个端口,用来实现文件上传。弹出窗口如图3-7所示。一般情况下,只要服务器能够启动,都会测试成功的。当图3-7 文件上传客户端Fig.3-7 The window of upload client测试成功后,点击“浏览”按钮,就能够选取本地文件,然后点击“上传”按钮,弹出“上传成功”之后,文件便成功上传到服务器指定的路径下。这里只能够实现单一文件的上传或者压缩包的上传,并不能够进行文件夹的上传。所以,如果要上传文件夹,要先将文件夹进行压缩,然后再上传到服务器。3.6 服务器等待连接的详细设计前面讲过,在这里有一个等待连接的线程。它的存在是必须的。如果在客户端对服务器进行连接,而且这个连接时间比较长的时候,如果服务器使用的是单线程,就会让服务器一直处于等待对方连接的状态,如果这个时候程序的其它动作准备完成,可以执行的时候,必须还得等待着连接完成,这样就让CPU处于了闲置状态,这样使得资源极大浪费。有了多线程就可以避免这个问题,能够将CPU充分地利用起来。在服务器端还有一个问题,如果Client1发送来消息,经由Server转发,在转发同时,Client2也发来消息经由Server转发,但是一次只能够转发一条消息。因此不能够将从Client1上获得一条消息转发一半后又去转发Client2发来的消息,所以在Server代码中的sendMsg方法前应该加synchronized限定词来给这个方法加锁。即是说,一旦转发一个客户端的消息,没有转发完毕的时候,不能够让另一个客户端要转发的消息占用
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智能家居系统互联互通标准下的智能家居行业市场细分报告
- 山西省资料员考试题库及答案
- 三国演义考试题及答案
- 2025年建设用地流转补偿协议
- 注塑员考试题及答案
- 中秋节主题活动方案范例(2篇)
- 2025年商业租赁权合同让渡协议
- 2025年社区管理服务托管合同样本
- 矿山法考试题及答案
- 漆工考试题及答案
- 《紫藤萝瀑布》《丁香结》《好一朵木槿花》
- 2023柔性棚洞防护结构技术规程
- 浙江工业大学学生综合测评分细则
- 河流地貌的发育 - 侵蚀地貌
- 离网光伏发电系统详解
- 英语初高中衔接音标
- 广告文案写作(第二版)全套教学课件
- 《国家电网公司电力安全工作规程(配电部分)》
- 金融学黄达ppt课件9.金融市场
- GB/T 3758-2008卡套式管接头用锥密封焊接接管
- GA/T 1105-2013信息安全技术终端接入控制产品安全技术要求
评论
0/150
提交评论