课程设计报告:聊天室系统

一、课程设计要求与目的

目的:编写一个小型Java聊天室系统,掌握Java网络通信、多线程、IO文件操作等高级应用编程技能。

要求:以课本第15章 Java网络通信例15.3、15.4的源代码为基础,编写一个小型Java聊天室系统。

完成如下功能:

1.多客户端模式下,实现客户与客户的单独通信,要求信息通过服务器中转

2.端到端的通信,实现并行通信模式(不再是你说一句,我说一句,一端的信息发送不受另一端的影响)

3.实现端到端的文件传输

4.添加图形界面(选做)

二、系统设计

1.设计原理与思想(Socket套接字通信原理,系统设计思想)

客户端和服务端都建立相应的Socket对象,客户端的Socket对象是显示调用 new完成的,而服务器端的Socket是调用SeverScoket的accept方法产生的。

服务器:创建一个SeverScoket,等待连接(accept方法处于阻塞状态)

客户端:创建一个Socket,连接到服务器。

SeverScoket接收到连接,创建一个Socket和客户的Socket建立专线连接,后续服务器和客户端的对话(这一对Socket)会在一个单独的线程上运行,然后服务器的SeverScoket继续等待连接,重复以上步骤。

过程图:

Java聊天室技术方面总结_java

这里实现客户端和客户端之间的通信,那么只需要在SeverScoket里用hashmap把对象引用存起来(来一个client我就add()在HasMap里),然后通过遍历获取socket实现转发消息。这里我写了一个send()方法专用于消息的发送;

对于文件传输的原理也一样,无非是加上文件的输入输出流,再加个判断的条件,你是要传文件还是还是进行普通的交流,在这里踩了不少的坑,各种空指针异常,需要输入两次才能转发给另外一个客户。

2.总体设计(类与类的关系)

服务端:

(1).MultiTalkServer.java(服务器主线程)

(2).ServerThread.java(处理客户请求的线程)

客户端:

(3)TalkClient.Java(这里的类只包含简单的消息的互发)

(4)Client.java(这里在TalkClient的基础上增添了文件传送)3.详细设计(单个类的设计,关键步骤或算法)

首先是.MultiTalkServer

Java聊天室技术方面总结_Java聊天室技术方面总结_02


这里采用HashMap来记录有多少个对象引用,key就是num;

Java聊天室技术方面总结_字符串_03

关于ServerThread就是不断从客户端读入字符流,然后转发给指定的一个客户端。

Java聊天室技术方面总结_Java聊天室技术方面总结_04

对于客户端client;

主要是与服务器建立连接,从键盘读入数据(文件),然后把字符串转换成字符流发送到服务器。接受从服务器转发的消息写在在**run()**里,

Java聊天室技术方面总结_字符串_05

三、系统测试

各功能测试用例,测试结果,结果说明

Java聊天室技术方面总结_Java聊天室技术方面总结_06


1,实现客户端的与指定客户端信息交流:

Java聊天室技术方面总结_Java聊天室技术方面总结_07

Java聊天室技术方面总结_字符串_08

Java聊天室技术方面总结_服务器_09

2,实现文件传输

3号向2号传文件,并输出文本内容,

Java聊天室技术方面总结_服务器_10


Java聊天室技术方面总结_Java聊天室技术方面总结_11


四、课程设计总结

对所做工作的总体总结:包括最终实现了哪些系统功能,使用了哪些Java编程技术、课程设计过程中遇到的问题、问题的解决以及收获

系统功能:(1)实现简单的信息交流,可以指定用户

(2)实现文件的传输

编程技术:采用了多线程,文件的输入输出流,线程锁。

问题(踩得坑,泪):

第一:字符转换问题,未采用UTF_8,也就是没有指顶类型,所以出现乱码,

Java聊天室技术方面总结_字符串_12


Java聊天室技术方面总结_java_13

修改后代码:

Java聊天室技术方面总结_Java聊天室技术方面总结_14

文件则是指定类型为GB2312(查了资料,只知道这样用可以)

Java聊天室技术方面总结_Java聊天室技术方面总结_15

第二:被自己蠢哭的bug

客户端从服务器端读取文件流里的东西,我写了个while循环,结果进行file传输的时候,以后再从键盘输入字符串的时候,字符串结果给我写到本地文件的文件里了,(害得我改了一天的bug,被自己蠢哭了)

Java聊天室技术方面总结_字符串_16

Java聊天室技术方面总结_客户端_17

把“ghj”写到了文件里了。正确的代码截图如下:

Java聊天室技术方面总结_客户端_18


第三:关于关闭流的;如果未使用文件流,但是在输入“bye”后进行关闭的操作的时候会报错,空指针异常

Java聊天室技术方面总结_客户端_19

正确的做法是先判断一下流文件输入流是否为空(if(fis!=null)),如果不为空再关闭.

Java聊天室技术方面总结_客户端_20


第四:改为指定用户发送消息

在服务端做了截取字符串的操作,也就是把从客户端传送过去的首字符截取出来作为需要发送的另一个客户端的序号,不过这里是String,需要转换成int型的,

Java聊天室技术方面总结_客户端_21

不过这也为传文件带来了bug,文本内容里并没有指定的客户端序号,那么传到服务器端的就是一串字符串,到执行int n = Integer.parseInt(strs[0]);操作会错

Java聊天室技术方面总结_服务器_22

由于在服务器端用截取字符串的首字母来获取所发客户端的序号,并用了Integer强制转换,也就是说所有从客户端输入的字符串的首个字符必须是数字,不然就会出现错误所以我在文件读入操作加上数字

Java聊天室技术方面总结_服务器_23

总结:理论必须要实践,这个聊天器的逻辑框架还是很简单的,但真正实践起来会碰到许多问题,这个小项目提高了我的代码能力,学会了新的debug的方法,为以后的项目做了一些铺垫,会少走一些弯路。