当前位置:文档之家› java课程设计聊天小程序

java课程设计聊天小程序

java课程设计聊天小程序课程设计指导书姓名学号班级一班课程名称Java课程设计课程性质设计时间2010年11月4日——2010年12月31日设计名称聊天小程序设计目的本次课程设计是对前面学过的面向对象的编程思想以及编程方法的一个总结、回顾和实践。

开始设计前学生一定要先回顾以前所学的内容,明确本次设计所要用到的技术点并到网上搜索以及查阅相关的书籍来搜集资料。

通过编写一个基于JA V A的应用系统综合实例,来掌握Java语言编程技巧。

设计要求1、使用图形用户界面。

2、能实现一个聊天室中多人聊天。

3、可以两人私聊。

计划与进度计划在两个月内完成任务,首先在前半个月内(11月4日--11月19日),构思通过网上(图书馆)的知识与课本上的相关内容的了解与认识,确认好选择的课题与怎样设计,基本的思路想好。

十五天(11月19日--12月5日)内参考资料争取完成服务端的程序,在12月5日--12月20日完成客户端的程序设计,在12月20日—12月30日内完成实现报告的填写工作。

在12月31日全面完成整个课题,并上交给老师。

任课教师意见备注课程设计报告课程:学号:姓名:班级教师:时间计算机科学与技术设计名称:聊天小程序日期:2010 年11月 4 日设计内容:设计一个在图形界面下,实现一个聊天室中多人聊天,也可以私聊的聊天小程序设计目的与要求:目的是为了更好的掌握java 这门课程的内容,同时更好的理解与掌握socket 编程,对所有面向对象的编程思想以及编程方法的一个总结、回顾和实践,掌握Java语言编程技巧。

要求使用图形用户界面。

能实现一个聊天室中多人聊天。

可以两人私聊。

(提示:使用socket通信)程序描述清晰准确,思路清晰,程序能够实现相应的功能。

设计环境或器材、原理与说明、主要完成的功能、设计思路和框图:设计环境或者器材:j d k或者j c编辑器,笔记本电脑两台,网线三条,小型交换机一个。

原理与说明:建立服务端与客户端的一个或者多个连接,其中服务器,使用Server Socket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。

客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

主要功能:1、实现服务端与客户端的连接,实现两者之间的信息交换。

2、实现了一个服务器可以与多个客户端实现连接,即实现了一个聊天室里面可以多人聊天。

3、亦可以实现私聊的功能。

设计思路与框图:服务器端接受客户端的连接请求,同时启动一个线程处理这个连接,线程不停的读取客户端输入,然后把输入加入队列中,等候处理。

在线程启动的同时将线程加入队列中,以便在需要的时候定位和取出。

大概的框图:chatServer端chatclient端︳创建ServerSocket对象在某端口提供监听服务等待来自chartclient的服务请求接受chartclient端的请求用建立连接创建Socket对象向server的监听端返回的Socket建立连接口请求通过向Socket中读写数据来数据通信通过向新的Socket中读写数据来与chartclient端通信与server端通信关闭Socket结束与当前的拆除连接关闭Socket结束与server的通信client的通信等待其他的请求关闭ServerSocket对象结束监听服务设计过程(步骤)或程序代码(可以加页):主要代码:服务端ChatServerclass SocketThread extends Thread{//线程类,用于和每个客户端连接static Vector<SocketThread> clientVector=new Vector<SocketThread>();//存放每个线程信息private Socket socket; //存放每个线程的Socket对象String nick; //存放每个线程的昵称private boolean firstRead;//用于判断是否为第一次接收数据SocketThread(Socket s){//构造函数socket=s;nick=null;firstRead=true;}private void noticeDelUser(){//通告所有线程的客户端,本用户退出String msg="###"+this.nick;for(int i=0;i<clientVector.size();i++)if(clientVector.get(i).nick.equals(this.nick)==f alse)sendMsg(i,msg);}private void delSocket(){//关闭socketnoticeDelUser(); //通告所有线程的客户端,本用户退出clientVector.remove(this);//从clientVector中移除本线程try{socket.close();System.out.println(socket.getInetAddress()+"断开连接!!");}catch(IOException closeError){}}private void noticeAddUser(){//通告所有线程的客户端,本用户进入String msg="##"+this.nick;for(int i=0;i<clientVector.size();i++)sendMsg(i,msg);}private void requestAllUser(){//本线程请求其他有用户信息int index=0;int i=0;for(i=0;i<clientVector.size();i++)if(clientVector.get(i).nick.equals(this.nick))break;index=i;for(i=0;i<clientVector.size();i++)if(index!=i){Stringmsg="##"+clientVector.get(i).nick;sendMsg(index,msg);}}private String msgForward(String msg){//对接收到的信息转发String name; //存放目的用户昵称String tempMsg; //存放生成的转发数据if(firstRead==true){ //若为第一次收到数据int i;for(i=0;i<clientVector.size();i++)//检查昵称是否存在if(clientVector.get(i).nick.equals(msg)==true)break;if(i>=clientVector.size()){//昵称不存在则:nick=msg; //在clientVector中添加本线程信息msg="#您使用的昵称:"+msg;//并通告所有线程的客户端,本用户进入noticeAddUser(); //以及请求其他有用户信息clientVector.add(this);requestAllUser();firstRead=false;}else{msg="#您输入的昵称已经存在,请重新输入:"; //昵称存在,发送系统提示}return msg;}if(msg.startsWith("!")==true){//若客户端发送密语name=msg.substring(1, msg.indexOf(' ')); //获得目的用户昵称,生成发送信息tempMsg=this.nick+"悄悄对"+name+"说:\r\n\t"+msg.substring(msg.indexOf(' '));}else{tempMsg=this.nick+":\r\n\t"+msg;//若为全体聊天name="610665c2a05631a7bc460993bae36ee6 "; //此name为特殊值,专指全体聊天}if(name.equals("610665c2a05631a7bc460993b ae36ee6")==false){//若为密语int i=0;for(;i<clientVector.size();i++)//查找目的客户线程在clientVector中的位置if(clientVector.get(i).nick.equals(name)==true )break;if(i>=clientVector.size()){//若找不到目的客户线程,则返回系统提示msg="#您所发送的用户名昵称不存在!!";}else{sendMsg(i,tempMsg);//找到目的客户线程并转发}}else{ //为全体聊天,全体转发int i=0;for(;i<clientVector.size();i++)sendMsg(i,tempMsg);}return msg;}private void sendMsg(int index,String msg){ //向特定客户转发,msg为转发信息SockettempSocket=clientVector.get(index).socket;//index为客户在clientVector中位置try{PrintWriter pw=newPrintWriter(tempSocket.getOutputStream(),tru e);pw.println(msg);}catch(IOException printError){}}public void run(){ //建立读写流String msg=null;InputStreamReader isr=null;BufferedReader br=null;try{isr=newInputStreamReader(socket.getInputStream());br=new BufferedReader(isr);}catch(IOException inOutError){System.out.println("无法与客户建立流!!");delSocket();return;}do{try{msg=br.readLine();}catch(IOException readError){System.out.println("读取流数据错误!!");delSocket();return;}System.out.println(msg);msg=msgForward(msg);//处理读取的数据if(msg.startsWith("#")==true){//若有系统提示返回,则返回系统提示try{PrintWriter pw=new PrintWriter(socket.getOutputStream(),true);pw.println(msg);}catch(IOException printError){}}}while(true);}}public class ChatServer {public static void main(String args[]){ServerSocket serverSocket=null;Socket socket=null;SocketThread st;try{serverSocket=new ServerSocket(8324);//监听端口8324System.out.println("服务器启动成功,正在监听8324端口!!");}catch(IOException e){System.out.println("不能使用端口8324,无法启动服务器!!");return;}while(true){try{socket=serverSocket.accept();//获得连接,并建立Socket}catch(IOException e){System.out.println("不能建立连接:"+socket.getInetAddress().toString()+"/"+socket .getPort());}st=new SocketThread(socket);//创建新线程System.out.println("建立连接:"+socket.getInetAddress().toString()+"/"+socket .getPort());st.start(); //开始新线程}}}客户端ChartClient主要代码:package ch02;private void initSocket(){ //对socket的初始化try{transferSocket=newSocket("localhost",8324); //与服务器建立连接ReceiveThread rt=new ReceiveThread(transferSocket,this);rt.start(); //开启新线程用于读取数据流}catch(IOException createError){//出现错误则退出程序welcomeInfo.setText("无法连接服务器!!");try{transferSocket.close();welcomeInfo.setText("与服务器连接已经断开!!");System.exit(0);}catch(IOException closeError){}System.exit(0);} //对输出流的初始化try{socketWriter=newPrintWriter(transferSocket.getOutputStream(),t rue);}catch(IOException streamError){welcomeInfo.setText("流建立错误!!");try{transferSocket.close();welcomeInfo.setText("与服务器连接已经断开!!");System.exit(0);}catch(IOException closeError){}System.exit(0);}}public void addNewMsg(String msg){//向chatRecord中追加数据chatRecord.append(msg+"\r\n");}public void setWelcome(String msg){//改变welcomeInfo值welcomeInfo.setText(msg);}public void windowIconified(WindowEvent e){}public void windowClosed(WindowEvent e){} public void windowDeactivated(WindowEvent e){}public void windowActivated(WindowEvent e){}public void windowClosing(WindowEvent e){//窗体关闭事件System.exit(0);}public void windowDeiconified(WindowEvent e){}public void windowOpened(WindowEvent e){}public void keyPressed(KeyEvent e){//对键盘事件的监视switch(e.getKeyCode()){case KeyEvent.VK_ENTER ://回车键,就发送信息sendMsg(); //向服务器发送信息break;case KeyEvent.VK_CANCEL://esc键则,friendList选中第0项friendList.select(0);transName.setText("发送给:"+friendList.getSelectedItem().toString());break;default :}}public void keyTyped(KeyEvent e){}public void keyReleased(KeyEvent e){} public void itemStateChanged(ItemEvent e){//监视friendList选中项变化if(e.getSource().equals(friendList)){//改变transName值transName.setText("发送给:"+friendList.getSelectedItem().toString());}}public void textValueChanged(TextEvent e){//若chatRecod字符多余100000 if(chatRecord.getText().length()>100000){//则清除部分历史记录,防止占用过大内存chatRecord.setText(chatRecord.getText().subs tring(chatRecord.getText().indexOf("\r\n")+2));}}public void actionPerformed(ActionEvent e){//点击sendButton则发送信息if(e.getSource()==sendButton){sendMsg();}}public void sendMsg(){//向服务器发送信息if(msgEditor!=null){if(friendList.getSelectedIndex()==0){//发送全体聊天信息socketWriter.println(msgEditor.getText());}else{ //发送密语,并回显socketWriter.println("!"+friendList.getSelect edItem().toString()+" "+msgEditor.getText());chatRecord.append(this.nick+"对"+friendList.getSelectedItem().toString()+"悄悄说:\r\n\t"+msgEditor.getText()+"\r\n");}}else //若发送信息为空,则系统提示chatRecord.append("!不能发送空消息\r\n");msgEditor.setText("");//将发送信息栏置空}}class ReceiveThread extends Thread{//监视输入流的类Socket socket; //连接服务器的socketClientWindows clientWindow;//主窗口ReceiveThread(Socket s,ClientWindows cw){//初始化socket=s;clientWindow=cw;}public void run(){String msg=null;BufferedReader br=null;try{ //建立输入流br=new BufferedReader(new InputStreamReader(socket.getInputStream()));}catch(IOException ReadError){clientWindow.setWelcome("读入流建立错误,程序关闭!!");try{socket.close();clientWindow.setWelcome("与服务器连接已经断开!!");System.exit(0);}catch(IOException closeError){}System.exit(0);}while(true){ //读取数据流的信息try{msg=br.readLine(); //获得信息}catch(IOException e){try{socket.close();clientWindow.setWelcome("与服务器连接已经断开!!");System.exit(0);}catch(IOException closeError){}System.exit(0);}msg=msgChange(msg);//转变读取到的信息if(msg!=null)clientWindow.addNewMsg(msg);//向聊天窗口添加新聊天内容}}private String msgChange(String msg){if(msg.startsWith("###")){//删除摸一个用户的信息for(inti=1;i<clientWindow.friendList.getItemCount();i ++){if(clientWindow.friendList.getItem(i).toString ().equals(msg.substring(3)))clientWindow.friendList.remove(i);}clientWindow.friendList.select(0);return null;}else if(msg.startsWith("##")){//增加某一个用户信息clientWindow.friendList.add(msg.substring(2 ));clientWindow.friendList.select(0);return null;}else if(msg.startsWith("#")){ //系统提示msg="!"+msg.substring(1);if(msg.startsWith("!您使用的昵称:"))clientWindow.nick=msg.substring(8);}return msg;}}设计结果与分析(可以加页):运行ChatServer服务端,运行ChatClient端的界面如下图:当打开两个或者多个客户端时:实现多人会话或者一对一的会话,界面如下图私聊即点击想要私聊的用户名即可;设计体会与建议:该实验中运用到了一些以前没有了解的东西:首先是. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。

相关主题