计算机网络课程设计实验报告QQ网络聊天室实现.docx
- 文档编号:4558909
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:26
- 大小:144.97KB
计算机网络课程设计实验报告QQ网络聊天室实现.docx
《计算机网络课程设计实验报告QQ网络聊天室实现.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计实验报告QQ网络聊天室实现.docx(26页珍藏版)》请在冰豆网上搜索。
计算机网络课程设计实验报告QQ网络聊天室实现
计算机网络课程设计报告
设计选题 网络聊天室
姓 名 马继鸣
学 号 0909090630
完成时间 2012-1-12
一、需求分析
聊天工具大多数由客户端程序和服务器程序外加服务器端,本程序采用客户机/服务器架构模式。
通过Java提供的Socket类来连接客户机和服务器并使客户机和服务器之间相互通信,由于聊天是多点对多点的而Java提供的多线程功能。
用多线程可完成多点对多点的聊天。
主要有两个应用程序,分别为服务器程序和客户端程序。
服务器应用程序主要用于消息转发,以及向所有用户发送系统消息等;客户端应用程序主要用于客户聊天记录的显示和信息输入。
采用Client/Server(C/S)体系结构,即客户机/服务器体系结构。
聊天服务器专门用于监控用户状态和转发消息,客户端负责接收消息的用户序列和消息文本发送到服务器。
该聊天系统实现群聊,用户登陆,退出聊天系统等功能。
二.设计
1.设计思想:
课程设计中利用JAVA实现基于C/S模式的聊天程序。
聊天室共分为服务器端和客户端两部分,服务器端程序主要负责侦听客户发来的消息,客户端登录到服务器端才可以实现正常的聊天功能。
2.功能设计
(1)服务器端的主要功能如下。
在特定端口上进行侦听,等待客户端连接。
用户可以配置服务端的侦听端口,默认端口为10000.
当停止服务时,断开所有用户连接。
(2)客户端的主要功能如下。
连接到已经开启聊天服务的服务端。
当服务器端开启的话,用户可以随时登录与注销。
用户可以向所有人发送消息。
3.详细设计
聊天室服务器端设计
聊天室服务器中主要的功能文件的功能如下:
MyButLis.java
主要用于添加事件侦听和动作处理,具体是服务器按钮中的“终止”“发送”的处理。
publicclassMyButLisimplementsActionListener
privateMyServeserver;
privateJTextFieldfiled1;
publicvoidactionPerformed(ActionEvente)
MyChatSet.java
服务器的线程队列,运行的方法,新增一个用户,则增加一个线程,并可以返回应答消息,给其余用户发送上下线信息,发送聊天信息(群聊私聊虽然已写,但是不知为何没有实现),发送用户列表。
关键在于除了线程之外,还定义了传输数据时的协议内容,如何分辨不同的信息,如聊天信息,登陆信息,上下线信息,并把信息完整准确的传递。
publicstaticArrayList
publicstaticvoidaddThread(MyserThreadth)//增加一个服务器线程对象
publicstaticvoidsendReMess(Stringtype,Stringstate,Strings,MyserThreadmyth)//返回应答信息
publicstaticvoidSendOSMess(Stringtype,Stringuser)//其他用户上下线信息
publicstaticvoidSendChatMess(Stringtype,Stringsender,Stringreciver,StringMess)//聊天信息
publicstaticvoidSendList//用户列表
MyCheckTool.java
保存用户的登陆信息,在其中建立一个码表,并且可以判断登陆信息是否合法。
//建立码表,用以保存用户信息
privatestaticMap
publicstaticbooleanCheckUser(MyUserInfouser)//验证用户名
MyFrame.java
建立服务器的主界面,关联侦听器。
并启动线程。
MyFramemy=newMyFrame();
my.ShowUI();//显示UI界面
publicvoidShowUI()
server.SetUP();
MyserThread.java
服务器线程类,定义输入输出流,发送读取信息,获取信息中相应标签的信息,用以判断用户名,密码,并可以中断连接。
this.socket=socket;
output=socket.getOutputStream();
input=socket.getInputStream();
publicvoidSendMess(Strings)//发送信息
publicStringReadMess()//读取信息
publicbooleanReadFirst()//将第一条信息读出来
publicStringGetValue(Stringtype,StringMess)
publicvoidPocess()//用以判断用户名、密码
publicvoidrun()//线程开始
publicMyUserInfogetUser()//获得该线程中的用户信息
MyServe.java
建立服务器,并启动该线程。
server=newServerSocket(inport);
Socketsc=server.accept();//获得socket对象
MyserThreadth=newMyserThread(sc);
th.start();//启动线程
客户端中主要的功能文件概述如下:
MyButLis.java
主要用于添加事件侦听和动作处理,具体是在客户端中的登陆注册发送等的处理。
publicMyButLis(MySocketChatsocket,JTextAreaarea1,JTextAreaarea2,MyLoginUIloginUI,JComboBoxbox)
publicvoidactionPerformed(ActionEvente)//设置动作监听器
MyChatFrame.java
客户端的图形界面。
关联侦听器。
并启动线程。
socket.setArea(area1);
socket.start()
MyLoginUI.java
登陆界面
MySocketChat.java
构建连接,截取字符串,发送登陆,注册,聊天信息,读取信息并判断设置启动线程方法。
publicMySocketChat(JTextFieldfield1,JTextFieldfield2,JTextAreaarea)//重写构造函数
publicStringGetValue(Stringtype,StringMess)//截取字符串
publicvoidSendMess(Stringtype)//发送登陆或者注册信息
publicvoidSendChat(Stringgetter,Stringchat)//发送聊天消息
publicStringReadMess()//读入的信息
publicvoidCheckMess(StringMess)//判断是什么消息
publicvoidrun()//设置启动方法
三.调试及测试
1、调试过程中遇到的主要问题及解决方法
在对于群聊和私聊的处理中,只实现了群聊,私聊虽有写,但是还没有实现,由于时间仓促,只能在寒假的其余时间努力完成。
还有就是如何在服务器与客户端的信息交互过程中,让他们能分辨是哪种信息并准确的读出来。
如果不能准确的分析,则数据的交换只能完成一种粗略的互换,而不能提取聊天内容等用户希望得到的信息。
为此,我专门看了很多相关的资料,在很多方法里面选取了一种自己容易理解的方法,我就定义了几种方式,分别辨认登陆注册聊天列表等信息:
"
//第一个与最后一个msg是标示一整句话的标示符type标示数据类型,两个
"
//其中sender,reciever,content分别指发送者、接受者、内容。
一些语法问题,在随着写程序的过程中,也慢慢纠正。
在服务器组建中,由于java对于网络连接强有力的支持和丰富的代码,让我没有遇到太难的问题。
2、对设计和编码的回顾讨论和分析
在获取系统时间这一块上,还是做得比较好。
Calendarca=Calendar.getInstance();
Dateda=newDate();//注意是在java.util.Date
SimpleDateFormatformat=newSimpleDateFormat("HH:
mm:
ss");//设置时间格式
da=ca.getTime();
time=format.format(da);
处理保存的注册信息时,可能做得不是很好,将hashmap写入文件,这样不能长期保存注册信息,只能在服务器不关闭的状态下,保存注册信息。
这个也会继续改进
3、程序运行的时空效率分析
本程序应用了线程对端口进行侦听。
线程一直后台开启,长期占用系统资源,但又能及时的实现端口监听和消息的收发。
4、测试数据集
服务器端程序主界面:
可以记录用户名,账号,IP地址,并可以发送系统消息
客户登陆注册界面
注册成功提示框
客户端运行界面
用户端测试界面
中间的(全部)按钮,点击后可以显示当前在线的好友列表,并选择聊天对象
四、经验和体会。
这是我第一次做java项目,只是这个学期选修了面向程序设计,每周一节课,很浅显的学习了java语言,在综合性如此强的项目设计中,感觉力不从心。
刚开始的一天里遇到了各种困难,不管是从原理上还是细节语法上,都感觉很难,索性前两天没有着手做,只是在看别人的项目制作过程去学习思路,或者是在看java中的iostream,swing,awt,net的基础原理和内容,然后的才慢慢一步一步的开始做,因为慢,所以坚持写,一共五天的时间,有两天没有睡觉。
还好有些设计基础,在最后终于可以完成一些基本的目标。
通过这次程序设计,进一步巩固、加深了我们所学专业课程的基本理论知识,理论联系实际,进一步培养了综合分析问题,解决问题的能力,进一步加强了JAVA的实际应用能力。
在网络知识中,也许这个知识点是可以铭记终身的。
在如此痛苦又快乐的第一次的后面,我想,要我继续写别的程序的话,我可以更有信息一些,一些流程已经了然于胸。
不管怎么样,只有自己动手做了,才能是自己牢牢掌握的知识。
所以我也会坚持去做些动手的内容,去锻炼自己。
关键段落的代码:
服务器端
Myserve.java
packagecom.javake.Server;
importjava.io.IOException;
import.ServerSocket;
import.Socket;
publicclassMyServe
{
privateintinport;
privateServerSocketserver;
//重写构造函数
publicMyServe(intinport)
{
this.inport=inport;
}
//建立服务器
publicvoidSetUP()
{
try{
server=newServerSocket(inport);
while(true)
{
//获得socket对象
Socketsc=server.accept();
MyserThreadth=newMyserThread(sc);
//启动线程
th.start();
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
publicServerSocketgetServer(){
returnserver;
}
}
MyserThread.java
packagecom.javake.Server;
importjava.io.*;
import.Socket;
publicclassMyserThreadextendsThread
{
privateSocketsocket;
privateMyUserInfouseIn;//用户对象
privateInputStreaminput;
privateOutputStreamoutput;
publicMyserThread(Socketsocket)//建立构造函数
{
this.socket=socket;//传入管道
try{
output=socket.getOutputStream();
input=socket.getInputStream();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
publicvoidSendMess(Strings)
{
byte[]b=s.getBytes();
try{
output.write(b);
output.flush();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
publicStringReadMess()
{
StringBufferbuff=newStringBuffer();
Strings="";
booleanend=false;
inti=0;
try{//循环
while(!
end)
{
i=input.read();
charc=(char)i;
buff.append(c);
s=buff.toString().trim();
if(s.endsWith(""))
{
s=newString(s.getBytes("ISO-8859-1"),"GBK").trim();
break;
}
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returns;
}
//将第一条信息独立出来
publicbooleanReadFirst()
{
StringMess=ReadMess();
Stringflag=GetValue("type",Mess);//截取标记
if(flag.equals("reg"))//判断是否为注册信息
{
Stringname=GetValue("name",Mess);//获得注册的用户
Stringpwd=GetValue("pwd",Mess);
MyUserInfouser=newMyUserInfo();
user.setName(name);
user.setPassWord(pwd);
if(MyCheckTool.SetUser(user))//验证注册是否成功
{
this.useIn=user;
MyChatSet.sendReMess("regResp","1","欢迎来到进入聊天室",this);
returntrue;}
else
{MyChatSet.sendReMess("regResp","0","用户已存在,注册失败",this);
returnfalse;}
}
if(flag.equals("login"))//判断是否为登陆用户
{Stringname=GetValue("name",Mess);//获得注册的用户
Stringpwd=GetValue("pwd",Mess);
StringIP=GetValue("IP",Mess);
MyUserInfouser=newMyUserInfo();
user.setName(name);
user.setPassWord(pwd);
user.setIPaddress(IP);
if(MyCheckTool.CheckUser(user))//验证登陆是否成功
{this.useIn=user;
MyChatSet.sendReMess("loginResp","1","欢迎来到进入聊天室",this);
MyChatSet.SendOSMess("onLine",this.useIn.getName());//发送用户上线消息
MyChatSet.addThread(this);//将线程加入队列
MyChatSet.SendList();//发送用户队列
returntrue;}
else
{MyChatSet.sendReMess("loginResp","0","用户名或账号错误",this);}
}
returnfalse;
}//否则返回登陆失败
publicStringGetValue(Stringtype,StringMess)
{
inti=Mess.indexOf("<"+type+">")+type.length()+2;
intj=Mess.indexOf(""+type+">");
Strings=Mess.substring(i,j);//获得截取的信息
returns;
}
publicvoidPocess()//用以判断用户名、密码
{
if(ReadFirst())//登陆或注册成功
{
Stringstr=ReadMess();
Stringtp=GetValue("type",str);
while(tp!
="offLine")
if(tp.equals("chat")){//获得类型标签
{
Stringsender=GetValue("sender",str);//获得内容
Stringgetter=GetValue("reciver",str);
Stringcontent=GetValue("content",str);
MyChatSet.SendChatMess("chat",sender,getter,content);//发送消息}
elseif(tp.equals("offline"))//判断是否为下线消息
{
Stringuser=GetValue("user",str);
MyChatSet.SendOSMess("offline",user);
}
elseif(tp.equals("login"))//注册后可能发来登陆消息
{
Stringname=GetValue("name",str);//获得注册的用户
Stringpwd=GetValue("pwd",str);
StringIP=GetValue("IP",str);
MyUserInfouser=newMyUserInfo();
user.setName(name);
user.setPassWord(pwd);
user.setIPaddress(IP);
if(MyCheckTool.CheckUser(user))//验证登陆是否成功
{
this.useIn=user;
MyChatSet.sendReMess("loginResp","1","欢迎来到进入聊天室",this);
MyChatSet.addThread(this);
System.out.println("二次注册或登录成功");
MyChatSet.SendList();
MyChatSet.SendOSMess("onLine",this.useIn.getName());//发送用户上线消息
}
else//将线程加入队列//发送用户队列
{
MyChatSet.sendReMess("loginResp","0","用户名或账号错误",this);
}
}
str=ReadMess();
tp=GetValue("type",str);
}
}
try{//关闭socket
socket.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
publicvoidrun()//线程开始
{
Pocess();
}
//获得该线程中的用户信息
publicMyUserInfogetUser(){
returnuseIn;
}
}
MyButLis.java
packagecom.javake.Server;
importjava.awt.event.*;
importjava.io.IOException;
importjavax.swing.JTextField;
publicclassMyButLisimplementsActionListener{
privateMyServeserver;
privateJTe
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 课程设计 实验 报告 QQ 网络 聊天室 实现