还剩21页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
J__a网络编程实践基于C/S的控制台聊天室课程设计说明书课程名称J__a网络课程实践题目基于C/S的控制台聊天室姓名董丽蓉学号200905143教学班号01指导教师王小刚兰州交通大学软件科学与工程系二○一一年月日任务书题目3基于C/S的控制台聊天室(1人)实现几个客户端的群聊(在控制台窗口显示聊天信息),信息经服务端转发和群发,多客户端使用多线程基于Socket注意在每一个客户端窗口要显示所有参与聊天者的聊天内容,包括谁发言及发言内容文档内容要求
1、在做上述题目时,正文要求包含4部分内容1)项目简述和目的2)解题基本思路;3)分析和设计4)主要程序源代码;5)运行截图;5)总结和体会
2、文档装订顺序1)封面;2)任务书;3)团队成员及分工列表;3)正文
3、打印格式要求纸型B5页边距上
2.54cm;下
2.54cm;左
2.2cm;右
1.9cm;装订线为0字体、格式要求题目2号黑体不加粗,居中,段前段后间距1行子标题字体为4号黑体所有的子标题均加粗,置于页面最左端,段前段后间距均设为
0.5行文章正文皆为5号宋体,行距为固定值22磅,字距为标准图、表的标题文字采用小5号黑体,表中的文字采用小5号宋体基于C/S的控制台聊天室
1、设计目的巩固所学的J__a语言基础知识,增进J__a语言的编辑基本功,拓展常用类库的应用,使我们通过教学环节与手段,把所学的课程及相关知识加以融会贯通,
二、设计内容运用J__a程序编写聊天室,实现简单的聊天功能它是图形界面,线程,流与文件系统等技术的综合应用其界面主要采用了J__a.awt包,J__a.swing包等程序实现了聊天室的基本功能,其中有
1.启动服务器
2.启动登录界面
3.进入客户端界面
4.发送信息
5.离开客户端界面
6.关闭服务器
3、分析
1.首先通过继承JFrame类构造服务器界面使服务器能够为每一个客户启动一个线程,记录客户的上下线行为、登录的IP,发送消息的时刻,监视客户的聊天记录,对于出现不文明的话语,在客户端进行屏蔽,并统计出现不文明用语的次数,超过三次提示警告信息,并将其踢出聊天室
2.设计客户端程序使其能够完成正常的通信功能,并且可以更改背景颜色,设置字体颜色
3.设计登录程序,使其显示登录的IP地址端口号,以及用户昵称,通过登录按钮可以调用客户端程序,实现;聊天功能
四、详细设计程序中引入的包1服务器端代码中用户自定义的类类名Server作用服务器的启动继承的类JFrame,构造服务器界面定义的对象TextArea文本域JSeverSocket服务器Socket客户端主要成员方法voidinit构造服务器端的界面publicvoidactionPerformedActionEvente按钮监听器publicvoidkeyPressedKeyEvente键盘监听器类名start作用启动服务器的线程继承的类名thread主要的成员方法Publicvoidrun启动服务器的线程类名SgServi__继承的类名thread主要的成员方法publicvoidrun处理单个客户的线程2用户登录相关的类类名login作用构造登录界面继承的类JFrame实现的接口ActionListener构造方法publiclogin主要的成员方法publicvoidactionPerformedActionEvente实现登录和取消按钮的监听器类名loginStart继承的类thread主要的方法publicvoidrun作用如果登录成功,则弹出客户端聊天窗口,如果登录失败,则打印出登录失败,以告知客户3客户端相关的类类名Client继承的类JFrame实现的接口ActionListener构造方法publicClientPrintStreamoutBufferedReaderinStringname主要的成员方法publicvoidre__ive接受服务端发来的信息五.主要程序源代码//聊天室服务器importimportimportimportimportimportclassServerextendsJFrame{privateTextAreamsgA=newTextArea;//服务器用来输入用的文本域privateTextAreaarea=newTextArea;//服务器显示消息的文本域privateTextFieldportT=newTextField8888;privatelist=new//在线客户列表privateServerSocketserver;//服务器privateSocketclient;//客户端private__pStringSocketcontainer=newHash__pStringSocket;//Hash__pvoidinit{Panelp1=newPanel;Panelp2=newPanel;Panelp3=newPanel;Panelp4=newPanel;Panelp5=newPanel;Panelp6=newPanel;Panelp7=newPanel;Panelp8=newPanel;Panelp9=newPanel;Panelp10=newPanel;//设置两个重要的文本框Labellb1=newLabel服务器界面;lb
1.setBackgroundnewColor250120150;Labellb2=newLabelport;BorderLayoutborder1=newBorderLayout;p
1.setLayoutborder1;p
1.addBorderLayout.__NTERarea;BorderLayoutborder2=newBorderLayout;p
5.setLayoutborder2;p
5.addBorderLayout.NORTHp3;p
5.addBorderLayout.__NTERmsgA;BorderLayoutborder3=newBorderLayout;p
7.setLayoutborder3;p
7.addBorderLayout.__NTERp1;p
7.addBorderLayout.SOUTHp5;p
7.setBackgroundnewColor250150200;JButtonstartButton=newJButton启动服务;JButtonsendButton=newJButton发送;JButtonflushButton=newJButton刷新列表;FlowLayoutf1=newFlowLayoutFlowLayout.LEFT;p
8.setLayoutf1;p
8.addlb2;p
8.addportT;p
8.addstartButton;p
8.addsendButton;p
8.addflushButton;p
8.setBackgroundnewColor250120150;BorderLayoutborder4=newBorderLayout;p
9.setLayoutborder4;p
9.addBorderLayout.__NTERp7;p
9.addBorderLayout.SOUTHp8;p
10.setLayoutnewBorderLayout;Labellb3=newLabel在线用户;lb
3.setBackgroundnewColor250120150;p
10.addlb3BorderLayout.NORTH;p
10.addlistBorderLayout.__NTER;area.setEditablefalse;BorderLayoutborder=newBorderLayout;this.addWindowListenernewWindowAdapter{publicvoidwindowClosingWindowEventarg0{System.exit0;}};this.setLayoutborder;this.addBorderLayout.NORTHlb1;this.addBorderLayout.__NTERp9;this.setTitle聊天服务器;this.setBounds100100600550;this.setVisibletrue;//“启动服务”按钮监听器startButton.addActionListenernewActionListener{publicvoidactionPerformedActionEvente{Threadt=newStart;t.start;}};//启动服务按钮监听器//发送按钮监听器sendButton.addActionListenernewActionListener{publicvoidactionPerformedActionEvente{Stringmsg=msgA.getText;ifmsg!=nullmsg!={//如果消息不为空Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;broadcasttime+[系统消息]:+msg;//那么广播这条消息area.appendtime+[系统消息]:+msg+\n;msgA.setText;}}};//end//刷新按钮监听器flushButton.addActionListenernewActionListener{publicvoidactionPerformedActionEvente{iflist!=null{list.removeAll;//清空在线用户列表,以便刷新}Set__p.EntryStringSocketmySet=container.entrySet;forIterator__p.EntryStringSocketit=mySet.iterator;it.hasNext;{//刷新列表__p.EntryStringSocketme=it.next;StringaClientName=me.getKey;SocketaClient=me.getValue;StringaClientAddress=aClient.getInetAddress.getHostAddress;list.addaClientName+---+aClientAddress;}}};msgA.addKeyListenernewKeyAdapter{//从键盘监听器---按下Enter发送消息publicvoidkeyPressedKeyEvente{intvalue=e.getKeyCode;ifvalue==KeyEvent.VK_ENTER{Stringmsg=msgA.getText;Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;broadcasttime+[系统消息]:+msg;//那么广播这条消息area.appendtime+[系统消息]:+msg+\n;msgA.setText;}}};}classStartextendsThread//启动服务器的线程{publicvoidrun{try{ifserver!=null!server.isClosed{area.append警告!服务器已在启动中!\n;}else{server=newServerSocketInteger.parseIntportT.getText;//启动服务器area.appendnewDate.toString+\n+[恭喜!*^__^*嘻嘻……]+服务器启动成功!+\n\n;}whiletrue{client=server.ac__pt;ThreadsgS=newSgServi__client;//为每位登录的客户创建一个线程sgS.start;//启动客户线程}}catchEx__ptione{System.out.printlncuowu1;e.printStackTra__;}}}//处理单个客户的线程classSgServi__extendsThread{privateSocketclient=null;//客户套接字privateBufferedReaderbr=null;//输入流privatePrintStreamps=null;privateintcounter=0;//记录是第几次接受用户的信息privateint__rk=0;//记录用户说不文明用语的次数privateStringname=null;SgServi__Socketclient{//构造方法this.client=client;}publicvoidrun{//run---begintry{br=newBufferedReadernewInputStreamReaderclient.getInputStream;ps=newPrintStreamclient.getOutputStream;Stringmsg=null;whilemsg=br.readLine!=null{//无限循环意味着可以和用户进行无限次交互ifcounter==0{name=msg;container.putnameclient;list.addname+---+client.getInetAddress.getHostAddress;Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.SECOND;Stringtime=hh+:+mm+:+;broadcasttime+name+上线了!\n\n;counter++;}else{ifmsg.equals你是个笨蛋{__rk=__rk+1;if__rk3{Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;singleComtime+[系统消息]:警告,请注意文明用语!client;area.appendtime+[系统消息]:+name+第+__rk+次使用了不文明用语,特此警告!;}else{//如果客户第三次说不文明的话,系统就把他踢出聊天室Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;if__rk==3{singleComtime+[系统消息]:+name+由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!client;//告诉他本人}removeClientnameclient;//从系统列表中删除这个人的信息//并向所有人广播这一消息broadcasttime+[系统消息]:+name+由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!\n;area.appendtime+[系统消息]:+name+由于多次使用了不文明用语,经警告无效,现已被踢出聊天室!;}}else{Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;area.appendtime+name+说+msg+\n\n;//同时向每个在线客户广播这则消息}}}}catchEx__ptionex{Calendarca=newGregorianCalendar;inthh=ca.getCalendar.HOUR_OF_DAY;intmm=ca.getCalendar.MINUTE;intss=ca.getCalendar.SECOND;Stringtime=newStringhh+:+mm+:+ss+;area.appendtime+name+下线了!\n;broadcasttime+name+下线了!\n;list.removename+---+client.getInetAddress.getHostAddress;container.removename;}}}voidremoveClientStringnameSocketclient{list.removename+---+client.getInetAddress.getHostAddress;container.removename;}voidbroadcastStringmsg{//broadcast---beginSet__p.EntryStringSocketmySet=container.entrySet;Iterator__p.EntryStringSocketit=mySet.iterator;Stringmessage=msg;whileit.hasNext{//如果列表中还有客户__p.EntryStringSocketme=it.next;SockettempClient=me.getValue;singleCommessagetempClient;//就把消息发给这个客户}}//向单个客户发送消息privatevoidsingleComStringmsgSocketaClient{//singleCommunition---begintry{PrintStreampw=newPrintStreamaClient.getOutputStream;Stringmessage=msg;pw.printlnmsg;}catchEx__ptionex{ex.printStackTra__;}}publicstaticvoid__inString[]args{newServer.init;//启动服务器窗口System.out.println服务器;}}//聊天室客户端importimportimportimportimportclassClientextendsJFrame{PrintStreamout;//输出流BufferedReaderin;//输入流Stringname;TextAreaarea=newTextArea;TextAreamsgA=newTextArea;TextFieldfrdNameT=newTextField10;Listlist=newList;Panelp10=newPanel;JButtonsendButton=newJButton发送;JButtoncloseButton=newJButton关闭;JButtonjb1=newJButton设置字体颜色;JButtonjb2=newJButton设置背景颜色;Labellb1=newLabel昵称;voidinit{this.pack;//设置几个面板Panelp1=newPanel;Panelp2=newPanel;Panelp3=newPanel;Panelp4=newPanel;Panelp5=newPanel;Panelp6=newPanel;Panelp7=newPanel;Panelp8=newPanel;Panelp9=newPanel;lb
1.setBackgroundColor.pink;//设置两个主要的文本框BorderLayoutborder1=newBorderLayout;p
1.setLayoutborder1;p
1.addBorderLayout.__NTERarea;area.setEditablefalse;FlowLayoutf2=newFlowLayoutFlowLayout.LEFT;p
3.setLayoutf2;p
3.addjb1;p
3.addjb2;BorderLayoutborder2=newBorderLayout;p
5.setLayoutborder2;p
5.addBorderLayout.NORTHp3;p
5.addBorderLayout.__NTERmsgA;p
5.setBackgroundColor.pink;BorderLayoutbroder3=newBorderLayout;p
7.setLayoutbroder3;p
7.addBorderLayout.__NTERp1;p
7.addBorderLayout.SOUTHp5;FlowLayoutf1=newFlowLayoutFlowLayout.RIGHT;p
8.setLayoutf1;p
8.addsendButton;p
8.addcloseButton;p
8.setBackgroundColor.pink;BorderLayoutbroder4=newBorderLayout;p
9.setLayoutbroder4;p
9.addBorderLayout.__NTERp7;p
9.addBorderLayout.SOUTHp8;//窗口关闭this.addWindowListenernewWindowAdapter{publicvoidwindowClosingWindowEventarg0{System.exit0;}};BorderLayoutbroder5=newBorderLayout;p
10.setLayoutbroder5;p
10.addBorderLayout.__NTERlist;p
10.setBackgroundColor.blue;//添加字体颜色的监听器jb
1.addActionListenernewActionListener{publicvoidactionPerformedActionEvente{JColorChooserchooser4=newJColorChooser;Colorcolor=chooser
4.showDialogClient.this我的调色盘Color.yellow;area.setForegroundcolor;msgA.setForegroundcolor;list.setForegroundcolor;}};jb
2.addActionListenernewActionListener{publicvoidactionPerformedActionEvente{JColorChooserchooser4=newJColorChooser;Colorcolor=chooser
4.showDialogClient.this我的调色盘Color.yellow;area.setBackgroundcolor;}};BorderLayoutborder=newBorderLayout;this.setLayoutborder;this.addBorderLayout.NORTHlb1;this.addBorderLayout.__NTERp9;this.addBorderLayout.EASTp10;this.setTitle聊天室客户端;this.setSize700600;this.setVisibletrue;sendButton.addActionListenernewActionListener{//“发送”按钮监听器publicvoidactionPerformedActionEvente{Stringmsg=msgA.getText;msgA.setText;//清空输入文本域out.printlnmsg;}};msgA.addKeyListenernewKeyAdapter{//键盘监听器---按下enter发送信息publicvoidkeyPressedKeyEvente{intvalue=e.getKeyCode;ifvalue==KeyEvent.VK_ENTER{Stringmsg=msgA.getText;msgA.setText;//清空文本域out.printlnmsg;}}};closeButton.addActionListenernewActionListener{//关闭监听器publicvoidactionPerformedActionEvente{System.exit100;}};}publicClientPrintStreamoutBufferedReaderinStringname{//构造方法this.out=out;this.in=in;this.name=name;lb
1.setText昵称:+name;init;//弹出客户端窗口out.printlnname;re__ive;//开始与服务器通信}publicvoidre__ive{//接收服务器端发来的信息try{Stringtext=null;whiletext=in.readLine!=null{this.area.appendtext+\n;//在area上读入的内容}}catchIOEx__ptione{e.printStackTra__;//TODOAuto-generatedcatchblock}finally{try{in.close;out.close;}catchEx__ptionex{ex.printStackTra__;}}}}//登录界面importimportimportimportimportclassloginextendsJFrameimplementsActionListener{TextField___Port;TextField___IP;TextField___Name;JButtonbtnLogin;JButtonbtnCan__l;SockettoServer;BufferedReaderin;PrintStreamout;publiclogin{Panelp1=newPanel;Panelp2=newPanel;Panelp3=newPanel;Panelp4=newPanel;Panelp5=newPanel;Labell1=newLabelport;Labell2=newLabelIP;Labell3=newLabel昵称;___Port=newTextField888815;___IP=newTextField15;___Name=newTextField小敏15;p
2.addl1;p
2.add___Port;p
3.addl2;p
3.add___IP;p
4.addl3;p
4.add___Name;GridLayoutg=newGridLayout31;//三行一列的网格布局管理器p
1.setLayoutg;//设置布局管理器p
1.addp2;//将组建添加到面板中p
1.addp3;p
1.addp4;p
1.setBackgroundnewColor100250100;//更改面板颜色btnLogin=newJButton登录;btnCan__l=newJButton取消;btnLogin.addActionListenerthis;btnCan__l.addActionListenerthis;BorderLayoutbroder1=newBorderLayout;this.setLayoutbroder1;p
5.addbtnLogin;p
5.addbtnCan__l;this.addBorderLayout.SOUTHp5;this.addBorderLayout.__NTERp1;this.setSize350250;this.setTitle用户登录;this.setResizablefalse;this.setLocation450250;this.setVisibletrue;this.setDefaultCloseOperationJFrame.EXIT_ON_CLOSE;//关闭窗口}publicvoidactionPerformedActionEvente{JButtonbutton=JButtone.getSour__;ifbutton.equalsbtnCan__l{dispose;//如果客户按了登录和取消按钮,那么登录窗口就关闭}else{LoginStartIs=newLoginStart;Is.start;this.dispose;}}classLoginStartextendsThread{publicvoidrun{intport=Integer.parseInt___Port.getText;//取得端口号Stringip=___IP.getText;Stringnam=___Name.getText;try{toServer=newSocketipport;in=newBufferedReadernewInputStreamReadertoServer.getInputStream;out=newPrintStreamtoServer.getOutputStream;//输出流newClientoutinnam;//如果登录成功,则弹出客户端聊天窗口dispose;//同时关闭登录窗口}catchEx__ptione2{System.out.println登录失败!;e
2.printStackTra__;}}}publicstaticvoid__inString[]args{newlogin;//启动登录窗口}}
6、相关截图登陆成功后,服务器界面显示踢出聊天室
七、总结及体会在设计的过程中了解到自己的知识比较有限,使得程序还不够完善,这一次的课程设计,让我懂得理论和实践相结合起来,从理论中得出结论,才能真正掌握这门技术,也提高了自己__思考的能力,在设计的过程中,可以自己解决问题真正体会到将一门知识学的更深入,必须加强实践,多练习,才能发现问题所在。