学 院:机电工程学院
专 业:计算机迷信与技术双学位 学 号:043545464 姓 名: 指导教员:李美安
职 称:传授
论文提交日期:二ОО八年四月
基于JAVA的聊天系统的设计与实现
摘 要
随着互联网的疾速发展,网络聊天工具已经作为一种重要的信息交流工具,受到越来越多的网平易近的青睐.今朝,出现了很多非常不错的聊天工具,其中应用比较广泛的有Netmeeting、腾讯QQ、MSN-Messager等等.该系统开辟主要包含一个网络聊天服务器程序和一个网络聊天客户程序两个方面.前者通过Socket套接字建立服务器,服务器能读取、转发客户端发来信息,并能刷新用户列表.后者通过与服务器建立毗连,来停止客户端与客户端的信息交流.其中用到结局域网通信机制的原理,通过直接继承Thread类来建立多线程.开辟中操纵了计算机网络编程的基本实际知识,如TCP/IP协议、客户端/服务器端形式(Client/Server形式)、网络编程的设计方法等.在网络编程中对信息的读取、发送,是操纵流来实现信息的交换,其中先容了对实现一个系统的信息流的分析,包含了一些基本的软件工程的方法.颠末分析这些情况,该局域网聊天工具采取Eclipse为基本开辟环境和java语言停止编写,首先可在短时间内建立系统应用原型,然后,对初始原型系统停止不竭修正和改进,直到形成可行系统 关键词:局域网 聊天 socket java
Abstract
Along with the fast development of Internet, the network chating tool has already become one kind of important communication tools and received more and more web cams favor. At present, many extremely good chating tools have appeared . for example, Netmeeting, QQ, MSN-Messager and so on. This system development mainly includes two aspects of the server procedure of the network chat and the customer procedure of the network chat. The former establishes the server through the Socket, the server can read and deliver the information which client side sends, and can renovate the users tabulation. The latter make a connection with the server, carries on communication between the client side and the client side. With the LAN correspondence mechanism principle, through inheritting the Thread kind to establish the multithreading directly. In the development, it uses
the elementary theory knowledge which the computer network programmes. for example, TCP/IP agreement, Client/Server pattern, network programming design method and so on. In the network programming, it realizes reading and transmission of the information, that is,informaton flows realize the information exchange, introduce information flow analysis for realizing a system, in which containes some basic software engineering methods. After analyzes these situations, this LAN chating tool takes Eclipse as the basic development environment and compiles in java language. first, it will establish the system application prototype in a short time. then, for the initial prototype system, it needs constantly revised and improved, until a viable system. Key words:LAN Chat Socket Java
目次
绪
论………………………………………………………………………………01
1.1 JAVA的网络功能与编
程…………………………………………………01
JAVA概
述…………………………………………………………………02
1.1.2 JAVA的特
点 ……………………………………………………………04
JAVA语言在网络上的应
用 ……………………………………………07
……………………………………………………………08 1.3 IP/TCP协议知
识 …………………………………………………………08
1.4 Socket的简
介……………………………………………………………09 2. 规划设
计…………………………………………………………………………11
……………………………………………………………………11
2.2需求分
析 …………………………………………………………………11
3. 系统分析与设计方
案……………………………………………………………12 3.1聊天系统的总体设计要
点 ………………………………………………12
……………………………………12 3.3功能模块布局图 …………………………………………………………13 4. 系统设计环境与测试…………………………………………………………26 4.1开辟环境和工
1.
具 …………………………………………………………26
4.2 硬件环境……………………………………………………………………26
4.3聊天系统的测试 …………………………………………………………26 5. 毕业设计总结 ……………………………………………………………………28 5.1毕业设计总结和展望……………………………………………………28
经历和感想…………………………………………………………………28
致
谢 ……………………………………………………………………………30
参考文献 …………………………………………………………………………31
1 绪论
随着互联网逐步普及,人们的生活和工作也越来越离不开信息网络的支持, 而聊天室是人们最罕见, 最直接的网上交流的方式.本聊天系统以聊天交流为主,为广大用户提供一个借助网络停止人际交往的平台,也是网络与现实最贴近的实用型网站.本文所先容的网络聊天系统是基于开放的JAVA应用程序开辟设计的,其主要特性是能动态、实时的完成信息的传递,且具有高效的交互性,更有效的处理客户请求,易于维护和更新,其运行所需环境及其工作流程和各个功能控件的工作原理将在本文依次先容,而且文中提供了部分程序源代码.
1.1JAVA的网络功能与编程
美国硅谷有一句行话,每10年~15年有一次循环.最近的一次循环就是从Java开端.
Java是一个由Sun公司开辟而成的新一代编程语言.使用它可在各式各样分歧种机器、分歧种操纵平台的网络环境中开辟软件.不管你使用的是哪种WWW阅读器,哪种计算机,哪种操纵系统,只要WWW阅读器上面注了然“支持Java”,你便可以看到生动的主页.Java正在逐步成为Internet应用的主要开辟语言.它完全改变了应用软件的开辟形式,带来了自PC机以来又一次技术革命,为迅速发展的信息世界增添了新的活力.
Sun的Java语言开辟小组成立于1991年,其目标是开辟消费类电子产品市场,例如,交互式电视、烤面包箱等.Sun外部人员把这个项目称为Green,那时WorldWideWeb还在图纸上呢.该小组的带领人是JamesGosling,是一位非常出色的程序员.他出生于1957年,于1984年加盟SunMicrosystem公司,之前在一家IBM研究机构工作.他是SunNeWs窗口系统的总设计师.也是第一个用C实现的EMACS的文本编辑器COSMACS的开辟者.
在研究开辟过程中,Gosling深刻体会到消费类电子产品和工作站产品在开辟哲学上的差别:消费类电子产品要求靠得住性高、费用低、尺度化、使用简单,用户其实不关心CPU的型号,也不欣赏专用昂贵的RISC处理器,他们需要建立在一个尺度基础之上,具有一系列可选的方案,从8086到80586都可以选取.
从C开端
为了使整个系统与平台无关,Gosling首先从改写C编译器着手.但是Gosling在改写过程中感到仅C是无法知足需要的,于是在1991年6月份开端准备开辟一个新的语言,那末给它起一个什么名字呢?Gosling回首向窗外望去,看见一棵老橡树,于是建一个目次叫Oak,这就是Java语言的前身(后来发现Oak已是Sun公司另外一个语言的注册商标,才改名为Java,即太平洋上一个盛产咖啡的岛屿的名字).
Gosling在开端写Java时,其实不局限于扩大语言机制自己,更注重于语言所运行的软硬件环境.他要建立一个系统,这个系统运行于一个宏大的、分布的、异构的网格环境中,完成各电子设备之间的通信与协同工作.Gosling在设计中采取了虚机器码(VirtualMachineCode)方式,即Java语言编译后发生的是虚拟机,虚拟机运行在一个诠释器上,每个操纵系统均有一个诠释器.这样一来,Java就成了平台无关语言.这和Gosling设计的SunNeWs窗口系统有着相同的技术味道.在NeWs中用户界面统一用Postscript描绘,分歧的显示器有分歧的Postscript诠释器,这样便包管了用户界面的杰出的可移植性.
PatrickNaughton也是Sun公司的技术骨干,曾是OpenWindows项目标负责人.当Naughton加入该小组后,整个工作停顿神速.颠末17个月的奋战,整个系统胜利完成.它是由一个操纵系统、一种语言(Java)、一个用户界面、一个新的硬件平台、三块专用芯片构成的.通常情况下,这样的项目在Sun公司要75个人干三年.项目完成后,在Sun公司外部做了一次展示和鉴定,观众的反应是:在各方面都采取了崭新的、非常大胆的技术.许多观赏者对Java留下了非常深刻的印象,特别得到Sun的两位带领人ScottMcNealy和BillJoy的关注,但Java的前途未卜.
Java语言的转折点
到了1994年,WWW已如火如荼地发展起来.Gosling意识到WWW需要一个中性的阅读器,它不依赖于任何硬件平台和软件平台,它应是一种实时性较高、靠得住平安、有交互功能的阅读器.于是Gosling决议用Java开辟一个新的Web阅读器.
这项工作由Naughton和JonathanPayne负责,到1994年秋天,完成了WebRunner的开辟工作.WebRunner是HotJava的前身,这个原型系统展示了Java可以带来的广阔市场前景.WebRunner改名为HotJava,并于1995年5月23日发表后,在财产界引起了宏大的轰动,Java的地位也随之而得到必定.又颠末一年的试用和改进,Java1.0版终于在1996年年头正式发表.
Java带来的影响
Java虽出现的时间不长,但已被业界承受,IBM、Apple、DEC、Adobe、SiliconGraphics、HP、Oracle、Toshiba、Netscap和Microsoft等大公司已经购买了Java的许可证.Microsoft还在其Web阅读器Explorer3.0版中增加了对Java的支持.
别的,众多的软件开辟商也开辟了许多支持Java的软件产品.如:Borland公司的基于Java的疾速应用程序开辟环境Latte;Metrowerks公司和NaturalIntelligence公司分别开辟的基于Machintosh的Java开辟工具;Sun公司的Java开辟环境JavaWorkshop;Microsoft也开辟出系列Java产品.数据库厂商如Illustra,Sybase,Versant,Oracle都在开辟支持HTML和Java的CGI(CommonGatewayInterface).在以网络为中心的计算时代,不支持HTML和Java,就意味着应用程序的应用范围只能限于同质的环境.
Intranet正在成为企业信息系统最佳的处理方案.它的优点表示在:便宜、易于使用和管理.用户不管使用何种类型的机器和操纵系统,界面是统一的Web阅读器,而数据库、Web页面、应用程序(用Java编的applet)则存在WWW服务器上.开辟人员只需维护一个软件版本,管理人员省去了为用户装置、升级、培训之苦,用户则只需一个操纵系统,一个Internet阅读器足矣.
我们可以设想未来的计算方式,每个HomePage的实质是一个多媒体应用程序,这些程序用Java来开辟.Java应用程序运行在异质的机器、异质的操纵系统之上,甚至于电冰箱、烤面包箱、防盗电子设备之中,用Internet把所有的电子设备毗连起来,通过TCP/IP停止信息的交流.Java应用程序之间既可以交换消息,也可以交换程序(一个Java的小应用程序applet).或许有一天,我们可以在Netscape阅读器里检查电冰箱的温度,向烤面包箱发一个电子邮件.
Java的出现是计算机信息交换的一个重要里程碑.在单机时代,程序过程之间靠共享存储停止变量交换;在网络时代,运行在分歧宿主机上的程序按网络协议停止无格式的消息(二进制字符流)交换,消息的语义由交换程序双方维护;在Java时代,运行在网络上的程序过程交换的是小应用程序(applet).小应用程序是什么?它是一个对象,由一组属性和方法构成,是一个可执行的实体;不但有数据的状态,而且有定义在数据上的操纵.未来可以停止代表(Agent)交换,代理有一定的智能性,
那即是信息交换的更高级阶段.
随着Internet的突起、Java的诞生,巨型的、臃肿的应用软件开端向小型化发展,由众多“生活”在Internet上的小应用程序(applet)相互协作完成信息的处理与传递.Java会加速应用软件的小型化、网络化的趋势.随着Internet的发展,软件必定是面向“大众”,而不是“少数人”的奢侈品,薄利多销将是网络应用软件的重要特点.分布式对象技术包管了用多少,下载多少. Java连同Internet,WWW正在改变应用软件的开辟和使用方式,一切都要围绕着网络,围绕着平台无关.很多人认为,Word、Excel等传统的信息处理工具都必定走向萎缩,因为它们是单机时代的产品.信息的价值在于使用和共享,Internet和Web是信息的使用和共享最快捷、最便宜的方式,Word将演化成为Web写作工具,Excel则将演化成Web上的电子表格. JAVA的特点
(一)JAVA的主要特点
Java语言有下面一些特点:简单、面向对象、分布式、诠释执行、鲁棒、 平安、体系布局中立、可移植、高性能、多线程以及动态性.
Java语言是一种面向对象的语言,它通过提供最基本的方法来完成指定的任务,只需懂得一些基本的概念,便可以用它编写出适合于各种情况的应用程序.Java略去了运算符重载、多重继承等恍惚的概念,,且通过实现自动渣滓收集大大简化了程序设计者的内存管理工作.别的,Java也适合于在小型机上运行,它的基本诠释器及类的支持只有40KB左右,加上尺度类库和线程的支持也只有215KB左右.库和线程的支持也只有215KB左右.
Java语言的设计集中于对象及其接口,它提供了简单的类机制以及动态的接口模子.对象中封装了它的状态变量以及相应的方法,实现了模块化和信息隐藏;而类则提供了一类对象的原型,而且通过继承机制,子类可使用父类所提供的方法,实现了代码的复用.
Java是面向网络的语言.通过它提供的类库可以处理TCP/IP协议,用户可以通过URL地址在网络上很方便地访问其它对象.
Java在编译和运行程序时,都要对可以出现的问题停止检查,以消除错误的发生.它提供自动渣滓收集来停止内存管理,防止程序员在管理内存时容易发生的错误.通过集成的面向对象的破例处理机制,在编译时,Java提示出可以出现但未被处理的破例,帮忙程序员正确地停止选择以防止系统的崩溃.别的, Java在编译时还可捕获类型声明中的许多罕见错误,防止动态运行时不匹配问题的出现.
用于网络、分布环境下的Java必须要防止病毒的入侵.Java不支持指针, 一切对内存的访问都必须通过对象的实例变量来实现,这样就防止程序员使用 “特洛伊”木马等欺骗手段访问对象的私有成员,同时也防止了指针操纵中容易 发生的错误.
Java诠释器生成与体系布局无关的字节码指令,只要装置了Java运行时系统,Java程序便可在任意的处理器上运行.这些字节码指令对应于Java虚拟 机中的暗示,Java诠释器得到字节码后,对它停止转换,使之可以在分歧的平 台运行.
与平台无关的特性使Java程序可以方便地被移植到网络上的分歧机器. 同时,Java的类库中也实现了与分歧平台的接口,使这些类库可以移植.别的,Java编译器是由Java语言实现的,Java运行时系统由尺度C实现,这使得Java 系统自己也具有可移植性.
Java诠释器直接对Java字节码停止诠释执行.字节码自己携带了许多编译时信息,使得毗连过程更加简单.
和其它诠释执行的语言如BASIC分歧,Java字节码的设计使之能很容易地直接转换成对应于特定CPU的机器码,从而得到较高的性能.
多线程机制使应用程序可以并行执行,而且同步机制包管了对共享数据的正确操纵.通过使用多线程,程序设计者可以分别用分歧的线程完成特定的行为,而不需要采取全局的事件循环机制,这样就很容易地实现网络上的实时交互行为.
Java的设计使它适合于一个不竭发展的环境.在类库中可以自由地加入 新的方法和实例变量而不会影响用户程序的执行.而且Java通过接口来支持多重继承,使之比严格的类继承具有更矫捷的方式和扩大性.
(二)JavaApplet
Java语言的特性使它可以最大限度地操纵网络.Applet是Java的小应 用程序,它是动态、平安、跨平台的网络应用程序.JavaApplet嵌入HTML语言,通过主页发布到Internet.网络用户访问服务器的Applet时,这些Applet 从网络上停止传输,然后在支持Java的阅读器中运行.由于Java语言的平安机制,用户一旦载入Applet,便可以放心地来生成多媒体的用户界面或完成复杂的计算而不必担心病毒的入侵.虽然Applet可以和图像、声音、动画等一样从网络上下载,但它其实分歧于这些多媒体的文件格式,它可以接纳用户的输入,动态 地停止改变,而不但仅是动画的显示和声音的播放.
(三)丰富的类库Java提供了大量的类以知足网络化、多线程、面向对象系统的需要.
1.语言包提供的支持包含字符串处理、多线程处理、破例处理、数学函 数处理等,可以用它简单地实现Java程序的运行平台.
2.实用程序包提供的支持包含哈希表、堆栈、可变数组、时间和日期等.
3.输入输出包用统一的\"流\"模子来实现所有格式的I/O,包含文件系统、 网络、输入
4.低级网络包用于实现Socket编程.
5.抽象图形用户接口包实现了分歧平台的计算机的图形用户接口部件, 包含窗口、菜单、滚动条、对话框等,使得Java可以移植到分歧平台的机器.
6.网络包支持Internet的TCP/IP协议,提供了与In-ternet的接口. 它支持URL毗连,WWW的即时访问,而且简化了用户/服务器模子的程序设计.
(四)Java和C、C++对于变量声明、参数传递、操纵符、流节制等,Java使用了和C、C++ 相同的传统,使得熟悉C、C++的程序员能很方便地停止编程.同时,Java为 了实现其简单、鲁棒、平安等特性,也摒弃了C和C++中许多分歧理的内容.
Java程序中,不克不及在所有类之外定义全局变量,只能通过在一个类中定 义公用、静态的变量来实现一个全局变量.例如:
ClassGlobalVar{ public static global_var; }
在类GlobalVar中定义变量global_var为public static,使得其它类 可以访问和修改该变量. Java对全局变量停止了更好的封装.而在C和C++中,依赖于不加封装 的全局变量常常造成系统的崩溃.
Java不支持C、C++中的goto语句,而是通过破例处理语句try,Catch, final等来代替C、C++中用goto来处理遇到错误时跳转的情况,使程序更可读 且更布局化.
指针是C、C++中最矫捷,也是最容易发生错误的数据类型.由指针所停止 的内存地址操纵常会造成不成预知的错误,同时通过指针对某个内存地址停止显 式类型转换后,可以访问一个C++中的私有成员,从而破坏平安性,造成系统的 崩溃.而Java对指针停止完全的节制,程序员不克不及直接停止任何指针操纵,例如 把整数转化为指针,或者通过指针释放某一内存地址等.同时,数组作为类在Java 中实现,杰出地处理了数组访问越界这一C、C++中不作检查的错误.
在C中,程序员通过库函数malloc()和free()来分配和释放内存,C++ 中则通过运算符new和delete来分配和释放内存.再次释放已释放的内存块或 未被分配的内存块,会造成系统的崩溃;同样,忘记释放不再使用的内存块也 会逐渐耗尽系统资源.而在Java中,所有的数据布局都是对象,通过运算符new 为它们分配内存堆.通过new得到对象的处理权,而实际分配给对象的内存可以 随程序运行而改变,Java对此自动地停止管理而且停止渣滓收集,有效防止了由 于程序员的误操纵而导致的错误,而且更好地操纵了系统资源.
在C、C++中,对于分歧的平台,编译器对于简单数据类型如int,float 等分别分配分歧长度的字节数,例如:int在IBMPC中为16位,在VAX-11中为 32位,这导致了代码的不成移植性,但在Java中,对于这些数据类型总是分 配固定长度的位数,如对int型,它总占32位,这就包管了Java的平台无关性.
在C、C++中,可以通过指针停止任意的类型转换,常常带来不服安性, 而Java中,运行时系统对对象的处理要停止类型相容性检查,以防止不服安的 转换.
C、C++中用头文件来声明类的原型以及全局变量、库函数等,在大的系 统中,维护这些头文件是很坚苦的.而Java不支持头文件,类成员的类型和访 问权限都封装在一个类中,运行时系统对访问停止节制,防止对私有成员的操纵.同时,Java中用import语句来与其它类停止通讯,以便使用它们的方法.
C、C++中的布局和结合中所有成员均为公有,这就带来了平安性问题. Java中不包含布局和结合,所有的内容都封装在类中.
C、C++中用宏定义来实现的代码给程序的可读性带来了坚苦.在Java中不支持宏,它通过关键字final来声明一个常量,以实现宏定义中广泛使 用的常量定义 1.1.3 JAVA语言在网络上的应用
Java程序可以获取网络上结点的图象、声音、HTML文档及文本等资源,并可以对获得的资源停止处理.例如Java程序可以每隔一定时间读取某结点提供的最新数据,
并以图表的形式显示出来.在编程处理上,一般先生成一个URL类型的对象,然后用 Java中相应的方法(method)获取该对象所代表的资源.下面罗列一个Java从网络上获取图象的的方法以说明.
Java Applet可以直接从网络上结点获取图象并显示出来,Java提供了如下方法可以创建对应于其他结点的图象:
getImage(new URL(字符串)) 其使用格式可有两种:
String url = “结点URL”; Image image; try {
image = getImage(new URL(url)); }
catch(Exception e){
System.out.println(“Can’t open the URL “);} 或
URL imgur=null; Image image; try {
imgur=new URL(“结点URL “); }catch (MalformedURLException e) {
System.out.println(“Can’t open the URL “); }
image=getImage(imgur);
前一种格式用“new URL(url)”生成 URL 对象, 并直接作为getImage的参数,后一种格式先用“new URL(url)”生成一个 URL对象,再传给getImage,两种格式实质上是一样的.
以上仅是Java在客户端应用的一些方面,今朝,Java更广泛的应用是在服务器端. JavaBeans技术
什么是JavaBeans?JavaBeans就是Java的可重用组件技术.ASP通过COM来扩大复杂的功能,如文件上载、发送email以及将业务 处理或复杂计算分离出来成为独立可重复操纵的模块.JSP通过JavaBeans实现了同样的功能扩大.JSP对于在Web应用中集成JavaBeans 组件提供了完善的支持.这种支持不但能缩短开辟时间(可以直接操纵经测试和可托任的已有组件,防止了重复开辟),也为JSP应用带来了更多的可伸缩性. JavaBeans组件可以用来执行复杂的计算任务,或负责与数据库的交互以及数据提取等.在实际的JSP开辟过程中,读者将会发现,和传统的ASP或 PHP页面相比,JSP页面将会是非常简洁的,由于JavaBeans开辟起来简单,又可以操纵Java语言的强大功能,许多动态页面处理过程实际上被封 装到了JavaBeans中.
1.3 IP/TCP协议知识 (1)IP、TCP协议的特点: TCP/IP(Transmission Control Protocol/Internet Protocol)是传输节制协议/网际协议的缩写, TCP/IP是当今网络互联的核心协议.TCP/IP协议的体系布局共有四个条理,即应用层、传输层、网络互联层和网络接口层.
IP协议的作用:第一,它是网络层的协议,提供互联网上数据传输的统一格式.第二,提供不成靠的无毗连的服务.第三,定义了互联网上的传输数据的基本单元,提供了供路由选择的信息,没有错误校验和处理的机制.
TCP协议的功能:错误节制——靠得住性、面向毗连、分段(Segment)、端标语.TCP是传输节制协议,是面向毗连的提供了一种靠得住的传输服务,它用三次握手和滑动窗口机制来包管传输的靠得住性,及停止流量节制.
TCP/IP协议具有以下特点:
1、协议尺度具有开放性,其独立于特定的计算机硬件及操纵系统,可以收费使用. 2、统一分配网络地址,使得每个TCP/IP 设备在网络中都具有唯一的IP地址. 3、实现了高层协议的尺度化,能为用户提供多种靠得住的服务. (2)TCP/IP协议停止传输数据传输的过程:
应用程序为了传输数据会调用TCP,将数据和对应的参数传给TCP,将TCP 数据包封装在IP包内,通过网络送给目标TCP.接纳方TCP在接纳到数据后通知上层应用程序,TCP将包管接纳数据的正确性.在实现TCP的主机上,TCP可以被当作是一个模块,和文件系统区别不大,TCP 也可以调用一些操纵系统的功能,TCP不直接和网络打交道,节制网络的任务由专门的设备驱动模块完成.TCP只是调用IP接口,向TCP提供所有TCP需要的服务.
(3)端标语:
有的时候,一个ip地址不克不及完整的标识一台服务器,这是应为一台物感性的计算机同时运行着多个应用程序,这就需要我们来区别同一台机子上的分歧的服务,所以就在传输层和应用层上设置接口,就是 端口.端话柄际是一个16位长的 地址,他的范围是0~65535之间,其中0~1023是熟知端口,主要是给提供服务的应用程序使用,这些端口是所有应用过程都只道的,1024~65535为一般端口,也称动态端口、毗连端口,用来随时分配要求通信的个客户端应用程序.在数据传输过程中,各种服务器不竭的检测分配给他的端口,一边发现要求和他通信的客户端. 1.4 Socket的简介
Socket,简称套接字,用于实现网络上客户和服务器之间的毗连.也就是说网络上两个或两个以上双工方式通信的过程之间总有一个毗连,这个毗连的端点成为套接字,套接字是在比较低的条理上通信的.
详细的说:一个服务器应用程序一般侦听一个特定的端口等待客户端的毗连请求,当一个毗连请求到达时,客户端和服武器端建立一个通信毗连,在毗连过程中,客户端被分配一个当地端口与一个socket建立毗连,客户端通过写socket来通知服务器,以读socket中的信息,近似的服务器也获得一个当地端口,它需要一个新的端标语来侦听原始端口上的其他毗连请求.服务器也通过它的当地端口毗连一个socket,通过读写和客户端通信.
Socket程序的工作过程:
1、建立Socket毗连:在通信开端之前由通信双方确认身份,建立一条专用的虚拟毗连通道.
2、数据通信:操纵虚拟毗连通道传送数据信息停止通道. 3、关闭:通信竣事时,再将所建的虚拟毗连裁撤. 详细如下: 服务器 1服务器三次握手: socket 2监听 3客户端etsocket 第一次握手:原主机发送一个带有本次毗连的序号的请求的一个数据帧
第二次握手:目标主机收到请求后,如果同意毗连,则发回一个带有一个本次毗连序号和源端机毗连序列号的确认.
第三此握手:源端机收到含有两次初始序列号的应答后,在向目标主机发送一个带有两次毗连的序列号的确认.
详细过程如下 第一次握手,主机A向主机B发送毗连请求 第二次握手,主机B收到主机A的请求,向主机A回发一个确认,,同时向主机A发送一个毗连请求 第三次握手,主机A收到主机B发送的数据包在向主机B发送一个确认毗连 主机A 主机B SYN=1,SEQ= 2 规划设计 2.1 课题来历 ACK=1,SYN=1,SEQ= 根据当前网络的需求,网络聊天越来越受各种网平易近所青睐.因此开辟网络聊天aaaaaaaaaa 是相当有需要,而且在网站内增加聊天功能,它不但可以提高网站的访问量,同时可以留着访客,更重要的是让访客透过聊天室实时的互相交流.而自己也学习过JAVA语言,对网络编程也较有兴趣,为了更好的考验自己对JAVA语言的掌握程度,自己就决议以《基于JAVA聊天设计与实现》为毕业设计,希望通过这一次的能进一步提高自己的网络开辟编程的才能. 聊天系统不过乎两个方面,服务器端和客户端.简单分析一下两个方面所要完成的任务,对设计这个程序来讲,等于完成了一半.首先来看一下服务器端的任务: 1.服务器端应当建立一个ServerSocket,而且不竭停止侦听是否有客户端毗连或者断开毗连(包含断定没有响应的毗连超时). 2.服务器端应当是一个信息发送中心,所有客户端的信息都传到服务器端,由服务器端根据要求分发信息. 以上就是服务器端最主要的两个任务.不丢脸出,服务器端的任务其实不复杂. 客户端应该完成的工作包含: 1.与服务器端建立通信通道,向服务器端发送信息. 2.接纳来自服务器的信息. 相对服务器而言,客户端的任务更加简单,有了以上的简单分析,可以知道,处理上述四个问题,即完成了该聊天系统的核心. 3 系统分析与设计方案 3.1 聊天系统的总体设计要点聊天系统的设计跟普通网站设计有着许多分歧的地方,普通网站设计所思索的因素,例如,普通网站需要对规划进入大量丑化以及动画设计等等,而聊天室只要提供知足访客双方直接实时聊天即可.因此,在设计聊天系统的过ACK=1 程中,必须要思索好以下几个设计要点:
1、实现思想
在Internet上的聊天程序一般都是以服务器提供服务端毗连响应,使用者通过客户端程序登录到服务器,便可以与登录在同一服务器上的用户交谈,这是一个面向毗连的通信过程.因此,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序.
2、服务器端工作流程
服务器端通过socket()系统调用创建一个Socket数组后(即设定了承受毗连客户的最大数目),与指定的当地端口绑定bind(),便可以在端口停止侦听listen().如果有客户端毗连请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket.然后登录成功的客户便可以在服务器上聊天了.
3、客户端工作流程
客户端程序相对简单,只需要建立一个Socket与服务器端毗连,成功后通过这个Socket来发送和接纳数据便可以了.
3 .2聊天系统的设计步调及功能模块划分
聊天系统工作原理图
(1)服务器程序模块
服务器与客户间通过套接口Socket(TCP)毗连.在java中使用套接口相当简单,JavaAPI为处理套接口的通信提供了一个类java.net.Socket,使得编写网络应用程序相对容易.服务器采取多线程以知足多用户的请求,并通过创建一个ServerSocket对象来监听来自客户的毗连请求,默许端口为9527,然后无限循环调用accept()方法承受客户程序的毗连.
服务器线程源码: package qq.server;
import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.util.*;
import qq.dao.hibernate.IServiceDao; import qq.entity.*;
public class ServerController { private User user; private Socket s; private IServiceDao dao; private ObjectInputStream ois; private ObjectOutputStream oos; private OnlineUser onlineUser; public ServerController(Socket s) { super(); dao=ServerMainClass.userDao; this.s = s; } public void handle() throws Exception { ois=new ObjectInputStream(s.getInputStream()); oos=new ObjectOutputStream(s.getOutputStream()); onlineUser=new OnlineUser(ois,oos); while(true){ Request req=(Request)ois.readObject(); ois.read(); RequestType type=req.getType(); if(type.equals(RequestType.exit)){ exitHandle(); break; }else if(type.equals(RequestType.login)){ loginHandle(req); }else if(type.equals(RequestType.register)){ registerHandle(); }else if(type.equals(RequestType.offline)){ offlineHandle(); break; }else if(type.equals(RequestType.changeInformation)){ changeInformationHandle(); }else if(type.equals(RequestType.modifypasswd)){ modifypasswdHandle(req); }else if(type.equals(RequestType.sendMessage)){ sendMessageHandle(req); }else if(type.equals(RequestType.receiveFile)){ receiveFileHandle(req); }else if(type.equals(RequestType.sendFile)){ sendFileHandle(req);
} } }
private void modifypasswdHandle(Request req) { Long id=Long.parseLong(req.getData(\"id\")); String oldpwd=req.getData(\"oldpwd\"); String newpwd=req.getData(\"newpwd\"); Response res=new Response(RequestType.modifypasswd); try { dao.updatePwd(id, oldpwd, newpwd); res.setData(1); try { oos.writeObject(res); } catch (IOException e) { e.printStackTrace(); } } catch (RuntimeException e) { try { oos.writeObject(res); } catch (IOException e1) { e1.printStackTrace(); } } }
private void changeInformationHandle() { try { User user=(User)ois.readObject(); Response res=new Response(RequestType.changeInformation); try { dao.updateUser(user); res.setData(1);//修改成功返回值带一个整形值 oos.writeObject(res); oos.flush(); } catch (RuntimeException e) { oos.writeObject(res);//失败则返回值不带参数 oos.flush(); e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
// // // // // // private void exitHandle() { try { s.close(); } catch (IOException e) { e.printStackTrace(); } }
//发送文件
private void sendFileHandle(Request req) { try { User u=(User)ois.readObject(); } catch (Exception e) { e.printStackTrace(); } }
//承受文件
private void receiveFileHandle(Request req) { }
//发送消息
private void sendMessageHandle(Request req) { Response res=new Response(RequestType.receiveMessage); Message message=null; try { message=(Message)ois.readObject(); res.setData(message); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } User to=message.getTo(); if(to==null){ sendToAllUser(res);//如果收信人为null,则发送信息给所有人 }else{ //发送信息给to和他自己 Response res1=new Response(RequestType.individualTalk); res1.setData(message); ObjectOutputStream o=null; Set o=ServerMainClass.userMap.get(u).getOos(); break; } } try { o.writeObject(res1); o.flush(); } catch (IOException e) { e.printStackTrace(); } } } //下线 private void offlineHandle() { try { ServerMainClass.userMap.remove(user); Response res=new Response(RequestType.offline); res.setData(user);//把下线用户发送给所有客户端 sendToAllUser(res); s.close(); } catch (IOException e) { e.printStackTrace(); } } private void registerHandle() { User user=dao.addUser(); try { oos.writeObject(user); System.out.println(user.getId()+\":\"+user.getName()); oos.flush(); } catch (IOException e) { e.printStackTrace(); } } //登录 private void loginHandle(Request req) { Long id=Long.parseLong((String)req.getData(\"id\")); String pwd=(String)req.getData(\"pwd\"); user=dao.getUser(id,pwd); Response res; try { Set User u=(User)iter.next(); if(u.equals(user)){ res=new Response(RequestType.haveOnline); oos.writeObject(res); oos.flush(); return;//该用户已经在线 } } res=new Response(RequestType.online); res.setData(user); oos.writeObject(res); oos.flush(); // 给刚上线用户发送在线用户列表 if(user!=null){ Set (2)客户程序模块 客户通过Socket(InetAddress,port)建立与服务器的毗连.服务器与客户都通过构造ObjectInputStream,ObjectOutputStream来建立输入输出流,然后双方通过该输入输出流来相互传递信息,一旦收到客户方的毗连请求,服务器accept()方法返回一个新建的Socket对象.客户端然后向服务器发送消息,比方文件传输等,服务器收到来自客户的请求后,针对分歧的消息处理请求.详细的源码如下: package qq.client; import java.awt.Color; import java.io.EOFException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import javax.swing.JOptionPane; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import java.net.*; import java.util.Calendar; import qq.client.panel.UserListPanel; import qq.client.windows.IndividualTalkWindow; import qq.entity.*; public class ClientThread extends Thread{ private ObjectInputStream ois; private ObjectOutputStream oos; private Socket s; private JTextPane receive; private JTextPane record; private JTextPane publicInfo; private UserListPanel userList; private SimpleAttributeSet set; public ClientThread(JTextPane receive, JTextPane record, JTextPane publicInfo, UserListPanel userList) { this.receive = receive; this.record = record; this.publicInfo = publicInfo; this.userList = userList; s=ClientMainClass.socket; ois=ClientMainClass.ois; oos=ClientMainClass.oos; set=new SimpleAttributeSet(); StyleConstants.setFontSize(set, 16); StyleConstants.setFontFamily(set,\"宋体\"); StyleConstants.setForeground(set, new Color(0,139,139)); } @Override public void run() { while(s.isConnected()){ try { Response res=(Response)ois.readObject(); if(res!=null){ RequestType type=res.getType(); if(type.equals(RequestType.online)){ onlineHandle(res); }else if(type.equals(RequestType.offline)){ offlineHandle(res); }else if(type.equals(RequestType.changeInformation)){ changeInformationHandle(res); }else if(type.equals(RequestType.modifypasswd)){ modifypasswdHandle(res); }else if(type.equals(RequestType.receiveMessage)){ receiveMessageHandle(res); }else if(type.equals(RequestType.individualTalk)){ individualTalkHandle(res); }else if(type.equals(RequestType.receiveFile)){ receiveFileHandle(res); }else if(type.equals(RequestType.publicInfo)){ publicInfoHandle(res); } } } catch (EOFException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } private void modifypasswdHandle(Response res) { if(res.getData()!=null){ JOptionPane.showMessageDialog(null, \"暗码修改成功\"); }else{ JOptionPane.showMessageDialog(null, \"暗码修改失败\\n服务器 忙,请稍后再试!\"); } } private void changeInformationHandle(Response res) { if(res.getData()!=null){ JOptionPane.showMessageDialog(null, \"修改成功\"); }else{ JOptionPane.showMessageDialog(null, \"服务器忙,请稍后再试!\"); } } private void publicInfoHandle(Response res) { String str=(String)res.getData(); publicInfo.setText(str); } private void receiveFileHandle(Response res) { } private void individualTalkHandle(Response res) { Message message=(Message)res.getData(); User user=message.getFrom(); if(!ClientMainClass.individual.containsKey(user.getId())){ int flag=JOptionPane.showConfirmDialog(null,user.getName()+\"请求与你私聊,是否承受?\ if(flag==JOptionPane.NO_OPTION){ return; } IndividualTalkWindow indi=new IndividualTalkWindow(user); ClientMainClass.individual.put(user.getId(), indi.getReceivedmessageArea().getTextPane()); indi.showMe(); } JTextPane jtp=ClientMainClass.individual.get(user.getId()); try {//输出信息发送人,时间 jtp.getDocument().insertString(jtp.getDocument().getLength(), user.getName()+\" \"+message.getTime()+\"\\n\ } catch (BadLocationException e) { e.printStackTrace(); } //输出信息 message.analysisMessage(jtp); } private void receiveMessageHandle(Response res) { Message message=(Message)res.getData(); if(ClientMainClass.shield.contains(message.getFrom().getId())){ return; } try {//输出信息发送人,时间 receive.getDocument().insertString(receive.getDocument().getLength(), message.getFrom().getName()+\"\"+message.getTime()+\"\\n\ } catch (BadLocationException e) { set); 因篇幅问题不能全部显示,请点此查看更多更全内容