基于socket网络聊天系统毕业论文

基于socket网络聊天系统毕业论文

ID:1393882

大小:2.44 MB

页数:33页

时间:2017-11-11

上传者:U-313
基于socket网络聊天系统毕业论文_第1页
基于socket网络聊天系统毕业论文_第2页
基于socket网络聊天系统毕业论文_第3页
基于socket网络聊天系统毕业论文_第4页
基于socket网络聊天系统毕业论文_第5页
资源描述:

《基于socket网络聊天系统毕业论文》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

基于socket网络聊天系统毕业论文目录绪论5选题的背景和意义5所做的主要工作5第一章系统所涉及到的技术61.1Java语言概述61.2Socket编程71.3TCP/IP协议81.4Swing简介101.5多线程技术介绍11第二章网络聊天系统分析132.1系统功能需求132.2可行性分析142.3.1社会可行性142.3.2用户可行性142.3.3技术可行性142.3.4经济可行性152.3系统开发环境15第三章系统设计实现163.1系统数据库设计163.1.1数据库概念设计163.2客户端与服务器的通信163.3客户端与客户端的通信173.4C/S的架构模式173.5系统的功能模块设计17第四章.各功能模块设计184.1服务器端的设计184.1.1服务器等待连接线程设计184.1.2服务器处理客户端信息线程设计194.2客户端设计234.2.1客户端登录模块设计234.2.2新用户注册模块设计2432 4.2.3客户端主界面模块设计244.2.4点对点通信模块设计254.2.5一对多通信模块设计254.2.6点对点文件传输模块设计26第五章.系统测试28结束语29致谢30参考文献31附录:基于SOCKET网络聊天系统源代码32绪论选题的背景和意义在Internet的计算机网络大潮中,人们已渐渐习惯于在网络上购物、聊天、看电影、交朋友等,人们的生活也是离不开网络。我们每天都在各种各样的网络应用中满足自己的需求。慢慢的,网络也无时无刻的改变人们的生活。当前人们进行信息交流的方式非常多,例如电报、电话、电子邮件等通讯手段。但是这些都存在不便利或者费用方面的问题,例如电子邮件,虽然费用不高,甚至可以免费使用,但是无法实现即时通讯,只能作为一种辅助交流的通讯手段。这时开发一套网络聊天系统变得尤为重要,通过该系统不但能够实现点对点的交流,还能够实现多人同时聊天,并且可以相互传递文件资料。最主要的是,它的费用非常低廉,信息处理速度快,这样人们才能在这个活动的社会中加强联系,从而创建出更多的财富和价值。现如今已有很多的网络聊天系统,例如腾讯的QQ、微信、阿里旺旺等等。这些网络聊天系统已经非常成熟了,不过它们都要求用户必须连接互联网才能够进行通信。所以根据用途的不同,我想开发的这一套网络聊天系统是在一个局域网中实现通信的,这样可以防止网络中的一些窥听,对信息安全性要求高的企业或是私人工作环境是一个很好的解决方案。该系统分为server端和客户端两部分组成,server端需要运行在服务器上,而客户端需要安装在用于通信的PC上,用户只需通过客户端连接至服务器上,就可以实现在局域网内的即时通信了。所做的主要工作本课题主要研究的是基于Socket的聊天软件,对于这个聊天软件的设计是32 分为服务器程序和客户端程序,本课题的目标是能实现用户在客户端与服务器端传递信息。主要研究开发内容是:熟悉系统开发平台,探索在此开发平台下,利用Socket编程技术、多线程开发技术、TCP/IP协议等进行聊天软件的实际开发。具体要实现的目标如下:(1)实现用户的注册、登陆、修改信息等功能(2)实现点对点的通信,即私聊(3)实现一对多的通信,即群聊(4)实现点对点的文件传输。第一章系统所涉及到的技术1.1Java语言概述JAVA是一种可以撰写跨平台应用软件的面向对象的程序设计语言,由升阳(SunMicrosystems)公司的詹姆斯·高斯林(JamesGosling)等人于1990年代初开发。它最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机、电话、闹钟、烤面包机等家用电器的控制和通讯问题。由于这些智能化家电的市场需求没有预期的高,Sun放弃了该项计划。就在Oak几近失败之时,随着互联网的发展,Sun看到了Oak在计算机网络上的广阔应用前景,于是改造了Oak,在1995年5月23日以“Java”的名称正式发布了。Java伴随着互联网的迅猛发展而发展,成为当今计算机业界不可忽视的力量和重要的发展潮流与方向。(1)Java语言的起源最早Java语言的出现是源于独立开发平台语言的需要,当时人们希望能编写出嵌入到各种家用电器等设备的芯片上、且易于维护的程序。它的出现是为了弥补当时的编程语言,例如C、C++等只能对特定的CPU芯片进行编译的缺陷。Java的设计者们就大胆设想让更换芯片的电器还是能够正确运行,无需重新编译芯片,因此Sun公司于1990年成立了由JamesGosling领导的开发小组,开始致力于开发一种可移植的、跨平台的语言,该语言能生成正确运行于各种操作系统、各种CPU芯片上的代码。经过他们的精心钻研和努力,便促成了Java语言的诞生。(2)Java语言的发展前景在2005年的JavaOne开发者大会上,JamesGosling做了题为“Java技术下一个10年贡献”的演讲,JamesGosling认为,Java技术提高了计算的“流动性”,就如同货币的发明提高了商品的流动性一样。无所不在的网络丰富了每个人的信息量,就如同可以兑换的货币产生了财富一样。由于从前的网络速度是很慢的,所以计算被束缚在特定的计算机上,而这种情况将一去不复返了。32 目前,全球Java开发人员已经超过450万,因此Java社区是一个充满活力和创新精神的团队,这正是Java更加繁荣的保障。为了保持Java的增长和推进Java社区的参与,Sun在JavaOne开发者大会上宣布开放Java核心源代码,以鼓励更多的人参与到社团活动中来,这是Sun为推进社团发展和维护Java技术兼容性而迈出的重要一步,同时也是Java技术在创新和社会进步上继续发挥重要作用的标志。随着Java的开源,在未来的十年里,Java的应用范围将变得更广。数字媒体将是Java的下一个目标,同时,Java将教育和健康作为未来Java发展过程中的两大重点应用领域。(3)Java的语法Java是面向对象的程序设计语言,其基本语法和C语言大致相同。从一定角度上讲,C语言加上面向对象功能就是C++。那么Java与C++有什么区别呢?简要地说,Java改进了C++的一些缺点,并增加了一些新的功能,从而变得比C++更加简单、易学,编写出来的程序也更具健壮性。下面就对它们进行一个简单的比较。îJava去掉了C语言的指针。如指针使用得当,对增强程序的功能有很大帮助,一旦使用不当,经常会导致死机。îJava没有了C语言中的预处理器。如#ifdef、#define、常量声明等都不使用了,当然也少了#include命令,从而也没有头文件(.h文件)。和C++相比,Java不支持多继承的概念,目的是为了避免对象和对象之间的关系复杂化。îJava增加了垃圾回收机制、异常处理和新的限定词等功能。这些几乎全部都是基于整个系统和程序本身安全性的考虑。î不论在何种平台上,Java基本数据类型的大小是不变的。1.2Socket编程Socket接口是访问Internet使用得最广泛的方法。如果你有一台刚配好TCP/IP协议的主机,其IP地址是192.168.0.1,此时在另一台主机或同一台主机上执行ftp192.168.0.1,显然无法建立连接。因"192.168.0.1"这台主机没有运行FTP服务软件。同样,在另一台或同一台主机上运行浏览软件如Netscape,输入"http://192.168.0.1",也无法建立连接。现在,如果在这台主机上运行一个FTP服务软件(该软件将打开一个Socket,并将其绑定到21端口),再在这台主机上运行一个Web服务软件(该软件将打开另一个Socket,并将其绑定到80端口)。这样,在另一台主机或同一台主机上执行ftp192.168.0.1,FTP客户软件将通过21端口来呼叫主机上由FTP服务软件提供的Socket,与其建立连接并对话。而在netscape中输入"http://192.168.0.1"时,将通过80端口来呼叫主机上由Web服务软件提供的Socket,与其建立连接并对话。在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像32 一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。在Java中所谓Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。重要的SocketAPI:java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法。Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。注意:其中getInputStream和getOutputStream方法均可能会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。1.3TCP/IP协议TCP/IP是TransmissionControlProtocol/Internet32 Protocol的简写,中文译名为传输控制协议/互联网络协议,该协议是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。TCP/IP协议的开发工作始于70年代,是用于互联网的第一套协议。(1)TCP/IP参考模型TCP/IP协议的开发研制人员将Internet分为五个层次,以便于理解,它也称为互联网分层模型或互联网分层参考模型,如下所示:物理层:对应于网络的基本硬件,这也是Internet物理构成,即我们可以看得见的硬设备,如PC机、互连网服务器、网络设备等,必须对这些硬设备的电气特性作一个规范,使这些设备都能够互相连接并兼容使用。网络接口层:它定义了将资料组成正确帧的规程和在网络中传输帧的规程,帧是指一串资料,它是资料在网络中传输的单位。互联网层:本层定义了互联网中传输的“信息包”格式,以及从一个用户通过一个或多个路由器到最终目标的"信息包"转发机制。传输层:为两个用户进程之间建立、管理和拆除可靠而又有效的端到端连接。应用层:它定义了应用程序使用互联网的规程。(2)网间协议IPInternet上使用的一个关键的底层协议是网际协议,通常称IP协议。我们利用一个共同遵守的通信协议,从而使Internet成为一个允许连接不同类型的计算机和不同操作系统的网络。要使两台计算机彼此之间进行通信,必须使两台计算机使用同一种"语言"。通信协议正像两台计算机交换信息所使用的共同语言,它规定了通信双方在通信中所应共同遵守的约定。计算机的通信协议精确地定义了计算机在彼此通信过程的所有细节。例如,每台计算机发送的信息格式和含义,在什么情况下应发送规定的特殊信息,以及接收方的计算机应做出哪些应答等等。网际协议IP协议提供了能适应各种各样网络硬件的灵活性,对底层网络硬件几乎没有任何要求,任何一个网络只要可以从一个地点向另一个地点传送二进制数据,就可以使用IP协议加入Internet了。如果希望能在Internet上进行交流和通信,则每台连上Internet的计算机都必须遵守IP协议。为此使用Internet的每台计算机都必须运行IP软件,以便时刻准备发送或接收信息。IP协议对于网络通信有着重要的意义:网络中的计算机通过安装IP软件,使许许多多的局域网络构成了一个庞大而又严密的通信系统。从而使Internet看起来好像是真实存在的,但实际上它是一种并不存在的虚拟网络,只不过是利用IP协议把全世界上所有愿意接入Internet的计算机局域网络连接起来,使得它们彼此之间都能够通信。(3)传输控制协议TCP32 尽管计算机通过安装IP软件,从而保证了计算机之间可以发送和接收资料,但IP协议还不能解决资料分组在传输过程中可能出现的问题。因此,若要解决可能出现的问题,连上Internet的计算机还需要安装TCP协议来提供可靠的并且无差错的通信服务。TCP协议被称作一种端对端协议。这是因为它为两台计算机之间的连接起了重要作用:当一台计算机需要与另一台远程计算机连接时,TCP协议会让它们建立一个连接、发送和接收资料以及终止连接。传输控制协议TCP协议利用重发技术和拥塞控制机制,向应用程序提供可靠的通信连接,使它能够自动适应网上的各种变化。即使在Internet暂时出现堵塞的情况下,TCP也能够保证通信的可靠。众所周知,Internet是一个庞大的国际性网络,网络上的拥挤和空闲时间总是交替不定的,加上传送的距离也远近不同,所以传输资料所用时间也会变化不定。TCP协议具有自动调整"超时值"的功能,能很好地适应Internet上各种各样的变化,确保传输数值的正确。因此,从上面我们可以了解到:IP协议只保证计算机能发送和接收分组资料,而TCP协议则可提供一个可靠的、可流控的、全双工的信息流传输服务。综上所述,虽然IP和TCP这两个协议的功能不尽相同,也可以分开单独使用,但它们是在同一时期作为一个协议来设计的,并且在功能上也是互补的。只有两者的结合,才能保证Internet在复杂的环境下正常运行。凡是要连接到Internet的计算机,都必须同时安装和使用这两个协议,因此在实际中常把这两个协议统称作TCP/IP协议。1.4Swing简介Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。Swing的产生主要原因就是AWT不能满足图形化用户界面发展的需要。AWT设计的初衷是支持开发小应用程序的简单用户界面。例如AWT缺少剪贴板、打印支持、键盘导航等特性,而且原来的AWT甚至不包括弹出式菜单或滚动窗格等基本元素。此外AWT还存在着严重的缺陷,人们使AWT适应基于继承的、具有很大伸缩性的事件模型,基于同位体的体系结构也成为其致命的弱点。随着发展的需要,Swing出现了,Swing组件几乎都是轻量组件,与重量组件相比,没有本地的对等组件,不像重量组件要在它们自己的本地不透明窗体中绘制,轻量组件在它们的重量组件的窗口中绘制。这一讲我们讲一下基本的Swing组件使用方法和使用Swing组件创建用户界面的初步方法。Swing是由100%纯Java实现的,Swing组件是用Java实现的轻量级(32 light-weight)组件,没有本地代码,不依赖操作系统的支持,这是它与AWT组件的最大区别。由于AWT组件通过与具体平台相关的对等类(Peer)实现,因此Swing比AWT组件具有更强的实用性。Swing在不同的平台上表现一致,并且有能力提供本地窗口系统不支持的其它特性。Swing采用了一种MVC的设计范式,即"模型-视图-控制"(Model-View-Controller),其中模型用来保存内容,视图用来显示内容,控制器用来控制用户输入。Swing外观感觉采用可插入的外观感觉(PluggableLookandFeel,PL&F)在AWT组件中,由于控制组件外观的对等类与具体平台相关,使得AWT组件总是只有与本机相关的外观。Swing使得程序在一个平台上运行时能够有不同的外观。用户可以选择自己习惯的外观。1.5多线程技术介绍多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行即可。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,由此带来的线程调度,同步等问题。(1)在Java中实现多线程。我们不妨设想,为了创建一个新的线程,我们需要做些什么?很显然,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切!真是神奇!Java是如何做到这一点的?通过类!作为一个完全面向对象的语言,Java提供了类java.lang.Thread来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程,我们以后的讨论都将围绕这个类进行。那么如何提供给Java我们要线程执行的代码呢?让我们来看一看Thread类。Thread类最重要的方法是run(),它为Thread类的方法start()所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它!方法一:继承Thread类,覆盖方法run(),我们在创建的Thread类的子类中重写run(),加入线程所要执行的代码即可。下面是一个例子:publicclassMyThreadextendsThread{intcount=1,number;publicMyThread(intnum){number=num;32 System.out.println("创建线程"+number);}publicvoidrun(){while(true){System.out.println("线程"+number+":计数"+count);if(++count==6)return;}}publicstaticvoidmain(Stringargs[]){for(inti=0;i〈5;i++)newMyThread(i+1).start();}}这种方法简单明了,符合大家的习惯,但是,它也有一个很大的缺点,那就是如果我们的类已经从一个类继承(如小程序必须继承自Applet类),则无法再继承Thread类,这时如果我们又不想建立一个新的类,应该怎么办呢?我们不妨来探索一种新的方法:我们不创建Thread类的子类,而是直接使用它,那么我们只能将我们的方法作为参数传递给Thread类的实例,有点类似回调函数。但是Java没有指针,我们只能传递一个包含这个方法的类的实例。那么如何限制这个类必须包含这一方法呢?当然是使用接口!(虽然抽象类也可满足,但是需要继承,而我们之所以要采用这种新方法,不就是为了避免继承带来的限制吗?)Java提供了接口java.lang.Runnable来支持这种方法。方法二:实现Runnable接口Runnable接口只有一个方法run(),我们声明自己的类实现Runnable接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是Runnable接口并没有任何对线程的支持,我们还必须创建Thread类的实例,这一点通过Thread类的构造函数publicThread(Runnabletarget);来实现。下面是一个例子:publicclassMyThreadimplementsRunnable{intcount=1,number;publicMyThread(intnum){number=num;System.out.println("创建线程"+number);}publicvoidrun(){while(true){System.out.println("线程"+number+":计数"+count);if(++count==6)return;32 }}publicstaticvoidmain(Stringargs[]){for(inti=0;i〈5;i++)newThread(newMyThread(i+1)).start();}}严格地说,创建Thread子类的实例也是可行的,但是必须注意的是,该子类必须没有覆盖Thread类的run方法,否则该线程执行的将是子类的run方法,而不是我们用以实现Runnable接口的类的run方法,对此大家不妨试验一下。使用Runnable接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代码,则仍必须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承Thread来得紧凑。(2)线程的四种状态1.新状态:线程已被创建但尚未执行(start()尚未被调用)。2.可执行状态:线程可以执行,虽然不一定正在执行。CPU时间随时可能被分配给该线程,从而使得它执行。3.死亡状态:正常情况下run()返回使得线程死亡。调用stop()或destroy()亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。4.阻塞状态:线程不会被分配CPU时间,无法执行。(3)线程的优先级线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得CPU时间时,线程调度系统根据各个线程的优先级来决定给谁分配CPU时间,优先级高的线程有更大的机会获得CPU时间,优先级低的线程也不是没有机会,只是机会要小一些罢了。你可以调用Thread类的方法getPriority()和setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)。(4)线程的同步由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。由于我们可以通过private关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块。32 第二章网络聊天系统分析2.1系统功能需求一般在开发一款软件时,最先考虑的就是用户的需求,所以进行需求分析是必不可少的步骤,它需要对目标项目提出完整、准确、清晰、具体的要求。首先,服务器需要同时连接很多个用户,并能提供给这些连接用户所需要的任务处理请求,这就要求服务器能同时处理多个Socket连接。服务器模型一般分为循环服务器和并发服务器,循环服务器一次只能处理一个连接,也就是说同一时间只能由一个用户连接到服务器进行消息处理,这种情况是不被允许的。因此我们将采用多线程方式的并发服务器来设计服务器端,这样将能从很大程度上提高服务器的运行效率。其次,客户端只需要连接到服务器便可以进行任务的处理工作,因此客户端的主要性能要求为图形界面运行的稳定性和对出错信息的及时反映。当一个窗体出现问题时能够及时的处理,让主程序不受影响。再者,所有的应用程序在运行过程中都会出现出错的情况,这种错误可能来自于程序本身,也可能是用户操作的失误所造成的。当有错误发生时,我们应该有一个很好的机制来保障错误能够及时地被排除。当应用程序出现了错误的时候我们就需要程序能提供给我们出错的信息,这样用户就能够很快的找出具体的出错原因,以便寻找合理的途径去解决它。2.2可行性分析可行性分析(FeasibilityAnalysis)也称为可行性研究,是在系统调查的基础上,针对新系统的开发是否具备必要性和可能性,对新系统的开发从技术、经济、社会的方面进行分析和研究,以避免投资失误,保证新系统的开发成功。可行性研究的目的就是用最小的代价在尽可能短的时间内确定问题是否能够解决。2.3.1社会可行性根据目前的计算机发展来看,公司几乎都是有网路需要的,无论是公网还是私网,很多公司和企业或者校园都提供了局域网信息服务。而网络聊天系统只要是用户的电脑连入局域网就能够访问,无须任何的其他昂贵设备,大大的节省了用户的资金。2.3.2用户可行性本系统服务的对象是各大公司或企业的工作人员,使用人员主要是掌握计算机基本操作技能的用户。加之,当前类似的系统操作简单,使用者能够很快上手。因此,在系统的使用方面不会存在问题。2.3.3技术可行性本次项目所使用的开发语言是Java,Java语言以其跨平台的特性一致都被业界认为是编程的最佳选择,经过多年的发展Java虚拟机已经升至1.7版本,在性能上有了很大提高,在API函数方面有了很多扩充和冗余的精简。同时,基于Java32 语言的设计模式的发展为软件的设计提供了大量的可供选择的解决方案,保证了系统软件的实现效率和运行过程中的逻辑健壮性。图2.1C/S架构示意图本次项目系统架构是C/S架构。如图2.1,因为C/S以它的灵活性,通用性,易操作性等特点在用户呈现方面一致是比较好的选择。目前,由于这种架构在系统构架方面的广泛采用,已经在系统构架上积累了大量的经验。所以本系统在技术上是可行的。2.3.4经济可行性从经济可行性的角度出发,系统在开发的过程中,主要应该考虑如何节约开发成本,缩短开发周期,以最小的投入获得最大的回报。为了保证软件产品的质量,系统的开发周期应该控制在1个月左右,并且要保证充足的调研时间和测试周期。整个网络聊天系统在开发过程中仅仅需要1到2名具有一定开发经验的程序员。所用的软件主要是Eclipse,该软件目前是开源和免费的。在硬件方面只需要一台交换机和专门用于编程和数据库服务的1到2台电脑,这些在目前市场上价格是可以接受的。因此在经济方面是可行的。2.3系统开发环境软件环境方面,本系统的采用的开发技术主要是Java,界面技术上采用的是Swing,并通过Socket和多线程技术来实现。系统开发工具是采用的Eclipse集成开发环境。在硬件环境方面,本系统的实现需要一台数据库服务器和一台服务器以及若干的终端电脑。以保证在系统完成之后有一个模拟环境,进行必要的测试。32 第三章系统设计实现3.1系统数据库设计本文在系统分析的基础上,对系统的规模和总体目标有了客观的估计,明确了设计任务和步骤。数据库设计是一个有序工作流程,它包括需求分析、概念设计、逻辑设计和物理设计三个阶段。在需求分析已经基本明确的前提下,本小结将主要从概念设计和逻辑设计阶段对数据库进行分设计。3.1.1数据库概念设计本系统的数据库概念设计主要用关系实体模型,即ER模型。利用ER方法进行概念设计,可分为三步进行:首先设计局部ER模式;然后把局部ER模式综合成一个全局ER模式;最后对全局ER模式进行细化,得到最终的ER模式,即概念模式。以下将按照这样的步骤进行。实体的划分方式有两种,一种是按系统的当前用户进行划分。另一种是按用户要求数据库提供的服务归纳成几类,是每一类应用访问的数据显地不通于其他类,然后为每类应用设计一个局部的ER模式。本文按用户划分设计局部ER模式。主要用于存储用户注册信息聊天记录以及对文件的存储等。3.2客户端与服务器的通信客户端和服务器是基于TCP/IP协议建立连接,并完成数据传输的,其流程图如下图所示。32 图3.2客户端和服务器创建流程图在Java的基于TCP/IP协议的Socket编程中,服务端使用ServerSocket类开创建,而客户端使用的Socket类。3.3客户端与客户端的通信客户端同客户端的通信是通过服务器转发的形式来实现的,其示意图如下图所示。图3.3通信示意图需要注意的是,客户端同客户端之间并没有直接的联系,而是通过服务器作为中转站的形式来完成数据传输的。这样可以保证服务器能够对客户端之间的数据进行处理,同时还能保证数据的安全性。32 3.4C/S的架构模式本聊天系统采用的是目前流行C/S架构来设置的,同时采用了三层架构。这三层分别是指数据库服务器、应用程序服务器以及应用程序客户端。这样可以合理的将各个任务分配至客户端和服务器端,从而降低系统的通信开销。图3.4架构示意图3.5系统的功能模块设计根据前面的需求分析和系统总体分析,最终设计系统的功能模块图如下图所示。图3.5系统的功能模块图第四章.各功能模块设计4.1服务器端的设计服务器端需要完成三大功能,分别是与客户端建立连接、监听客户端消息以及操作数据库。32 由于会有多个用户同时访问服务器,为了适应多个用户的并发访问。本系统服务器端程序需要借助于Java语言的多线程机制来完成。4.1.1服务器等待连接线程设计具体的实现为在服务器成功创建后,会启动一个循环等待连接线程,该线程专门用来负责接收客户端请求,其实现代码如下所示。classServerAcceptextendsThread{publicvoidrun(){try{while(true){Sockets;s=ss.accept();ServerReadsr=newServerRead();sr.srs=s;sr.start();}}catch(IOExceptione){e.printStackTrace();}}}4.1.2服务器处理客户端信息线程设计当服务器等待连接线程接收到一个新的套接字连接后,就会启动一个新的服务器处理客户端信息线程来负责本服务器和该客户端之间的连接,同时该在线程中的run方法中处理客户端的请求。等待连接线程将继续等待下一个客户端连接请求。前一个请求在完成所有的交互操作后自动退出,同时连接也将关闭,其实现代码如下。classServerReadextendsThread{Socketsrs;Stringsadress;BufferedReaderbr;Stringusername;publicvoidrun(){try{br=newBufferedReader(newInputStreamReader(srs.getInputStream()));PrintStreamps=newPrintStream(srs.getOutputStream());32 sadress=srs.getInetAddress().toString().substring(1);while(true){Stringcodeline=br.readLine();if(codeline!=null){System.out.println(codeline+";;;;;;;;;;");if(codeline.startsWith("@")){//有人上线,并通知在线用户更新在线人员列表if(readFromFile(codeline.split("@")[1],codeline.split("@")[2]).equals("true")){if(!mapip.containsKey(codeline.split("@")[1])){System.out.println(codeline+"有人登陆了");this.username=codeline.split("@")[1];mapps.put(username,ps);mapip.put(username,sadress);System.out.println(username);Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}32 }else{ps.println("@two");}}else{ps.println("@false");}}elseif(codeline.startsWith("end=")){//有人下线,并通知在线用户更新在线人员列表Stringleave=codeline.split("=")[1];System.out.println(leave+"下线");mapps.remove(leave);mapip.remove(leave);Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}elseif(codeline.startsWith("giveip=")){//要ip,并发回对应IpStringnme=codeline.split("=")[1];32 Stringtonme=codeline.split("=")[2];PrintStreampss=mapps.get(nme);pss.println("ip="+tonme+"="+mapip.get(tonme));}elseif(codeline.startsWith("=@")){Stringna=codeline.split("=@")[1];Stringpsw=codeline.split("=@")[2];if(writeToFile(na,psw)){ps.println("=true");}else{ps.println("=false");}}elseif(codeline.contains("=states=")){Stringuser=codeline.split("=")[0];Stringstates=codeline.split("=")[2];if(states.equals("在线")){Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}32 }else{Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();if(!a.equals(user))sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}}else{//发送群消息Setset=mapps.keySet();Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(codeline);}}}}}catch(IOExceptione){32 //TODOAuto-generatedcatchblocke.printStackTrace();}}}4.2客户端设计4.2.1客户端登录模块设计客户端登录模块用来判断用户是否为合法用户,如果是则可以登录到客户端主界面,否则将无法进入。系统登录窗口的运行效果如图4.1所示。图4.1登录窗口在登录窗口中输入正确的账户和密码信息,然后单击“登录”按钮,即可向服务器发送登录请求。服务器会对用户的登录信息进行判断,然后返回相应的处理结果。4.2.2新用户注册模块设计在登录窗口中单击“注册新用户”标签,这是将打开注册新用户窗口,其运行效果如图4.2所示。图4.2注册新用户窗口32 在注册新用户窗口窗口中输入用户账户、用户密码以及确认密码信息后,单击“注册”按钮即可向服务器发送注册请求信息。服务器会对用户的注册信息进行判断,然后返回相应的处理结果。如果处理成功,将向数据库中添加一条用户记录。4.2.3客户端主界面模块设计用户在登录成功后,将会关闭登录窗口,同时打开客户端主界面,其运行效果如图4.3和4.4所示。图4.3客户端主界面图4.4客户端主界面客户端主界面是用户进入点对点聊天或者聊天室的通道,用户的所有操作都是通过主界面来实现的。4.2.4点对点通信模块设计在客户端主界面中双击需要聊天的对象,就可以打开聊天消息窗口,从而开始点对点的通信,其运行效果如图4.5所示。32 图4.5聊天消息窗口在聊天消息窗口的上半部分界面用来显示聊天记录,下半部分用来输入聊天内容,输入完成后,单击其中的“发送信息”按钮既可以实现消息的发送。4.2.5一对多通信模块设计在客户端主界面中单击“进入聊天室”按钮,就可以打开聊天室消息窗口,从而开始一对多的通信,其运行效果如图4.6所示。图4.6聊天室消息窗口在聊天室消息窗口中可以看到所有用户发送的消息,用户也可以自己输入消息内容,然后通过单击“发送信息”按钮来发送消息内容。32 4.2.6点对点文件传输模块设计在聊天消息窗口中,不但可以发送普通的消息文本,还可以发送文件。只需要单击窗体底部的“发送文件按钮”即可,这是将打开文件选择框用来选择需要传送的文件。选择完成后,在界面上将显示“正在等待对方接收文件”提示信息,其运行效果如图4.7所示。图4.7发送文件同时在好友的聊天消息窗口中将显示“test向你发送了文件:无标题(2).wma请及时接收文件”的提示信息,其运行效果如图4.8所示。图4.8接受文件单击其中的“接受文件”32 按钮,即可打开文件保存对话框,用来选择文件的保存路径。保存完成后,界面将提示“开始发送文件”的提示信息,当文件发送完成后,界面将提示“文件发送完毕”的提示信息,其运行效果如图4.9所示。图4.9文件发送成功第五章.系统测试当系统搭建好之后,考虑到系统运行的稳定性和实用性,所以需要进行测试,其目的是通过与系统的需求相比较,发现所开发的系统与用户需求不符或矛盾的地方,从而提出更加完善的方案.。它的的任务是尽可能彻底地检查出程序中的错误,提高软件系统的可靠性,其目的是检验系统"做得怎样?"。这阶段又可分为三个步骤:模块测试,测试每个模块的程序是否有错误;组装测试,测试模块之间的接口是否正确;确认测试,测试整个软件系统是否满足用户功能和性能的要求。该阶段结束应交付测试报告,说明测试数据的选择,测试用例以及测试结果是否符合预期结果。测试发现问题之后要经过调试找出错误原因和位置,然后进行改正。是基于系统整体需求说明书的黑盒类测试,应覆盖系统所有联合的部件。系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不相符合或与之矛盾的地方。系统测试的对象不仅仅包括需要测试的产品系统的软件,还要包含软件所依赖的硬件、外设甚至包括某些数据、某些支持软件及其接口等。因此,必须将系统中的软件与各种依赖的资源结合起来,在系统实际运行环境下来进行测试。32 结束语通过这次对网络聊天系统的开发与设计,我学到了很多的知识,包括采用Java的Socket、Swing以及多线程等技术等,在该系统中实现了网络聊天系统的常用基本功能,发送聊天文字,即时文件传阅。可以满足大部门用户在组建局域网后作为安全便捷的内部交流工具之用。32 致谢在本次毕业设计的开发过程中,我曾经遇到了很多的困难,有知识储备量的不足,也有失败带来的焦虑心理。不过也有很多帮助我的人,同学的帮助,导师的指点,都让我在一次次的失败面前找到解决问题的方法,让我在面对这些困难的时候,没有退缩而是选择了激流勇进,最终在指导老师和同学们的帮助下将问题一个个的解决。本设计由于时间有限,功能上还是比较简单,没有华丽的界面和强大的功能。不过我相信在以后的学习中会继续完善它。32 参考文献[1]Java编程思想[M],机械工业出版社,2007.6[2]30天学通Java项目案例开发[M],电子工业出版社,2009.7[3]JavaSwing图形界面开发与案例详解[M],清华大学出版社,2008.12[4]JavaTCP/IPSocket编程(原书第2版)[M],机械工业出版社,2009.1[5]Java范例大全[M],机械工业出版社,2009.10[6]Java开发实战经典[M],清华大学出版社,2009.7[7]Java程序设计:一种跨学科的方法[M],清华大学出版社,2009.5[8]Java程序设计教程[M],机械工业出版社,2008.9[9]Java从入门到精通[M],清华大学出版社,2008.8[10]Java网络编程技术与实践[M],清华大学出版社,2008.832 附录:基于socket网络聊天系统源代码classServerAcceptextendsThread{publicvoidrun(){try{while(true){Sockets;s=ss.accept();ServerReadsr=newServerRead();sr.srs=s;sr.start();}}catch(IOExceptione){e.printStackTrace();}}}classServerReadextendsThread{Socketsrs;Stringsadress;32 BufferedReaderbr;Stringusername;publicvoidrun(){try{br=newBufferedReader(newInputStreamReader(srs.getInputStream()));PrintStreamps=newPrintStream(srs.getOutputStream());sadress=srs.getInetAddress().toString().substring(1);while(true){Stringcodeline=br.readLine();if(codeline!=null){System.out.println(codeline+";;;;;;;;;;");if(codeline.startsWith("@")){//有人上线,并通知在线用户更新在线人员列表if(readFromFile(codeline.split("@")[1],codeline.split("@")[2]).equals("true")){if(!mapip.containsKey(codeline.split("@")[1])){System.out.println(codeline+"有人登陆了");this.username=codeline.split("@")[1];mapps.put(username,ps);mapip.put(username,sadress);System.out.println(username);Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");32 }Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}else{ps.println("@two");}}else{ps.println("@false");}}elseif(codeline.startsWith("end=")){//有人下线,并通知在线用户更新在线人员列表Stringleave=codeline.split("=")[1];System.out.println(leave+"下线");mapps.remove(leave);mapip.remove(leave);Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}32 elseif(codeline.startsWith("giveip=")){//要ip,并发回对应IpStringnme=codeline.split("=")[1];Stringtonme=codeline.split("=")[2];PrintStreampss=mapps.get(nme);pss.println("ip="+tonme+"="+mapip.get(tonme));}elseif(codeline.startsWith("=@")){Stringna=codeline.split("=@")[1];Stringpsw=codeline.split("=@")[2];if(writeToFile(na,psw)){ps.println("=true");}else{ps.println("=false");}}elseif(codeline.contains("=states=")){Stringuser=codeline.split("=")[0];Stringstates=codeline.split("=")[2];if(states.equals("在线")){Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}32 else{Setset=mapps.keySet();Iteratorit=set.iterator();StringBuffersb=newStringBuffer(",");while(it.hasNext()){Stringa=(String)it.next();if(!a.equals(user))sb.append(a+",");}Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(sb.toString());}}}else{//发送群消息Setset=mapps.keySet();Iteratoriit=set.iterator();while(iit.hasNext()){Stringa=(String)iit.next();PrintStreampss=(PrintStream)mapps.get(a);pss.println(codeline);}}}}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}32

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭