`
古尔丹之颅
  • 浏览: 30216 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

java小项目之简单聊天室

阅读更多

       今天很郁闷,好久没有这种感觉了!在蓝杰弄了近一天的聊天室,下午还是决定去打篮球,放松一下!打了一场酣畅淋漓的全场比赛,最终打平了,结果不是最希望看到的,但是期间的努力却是集体7个人共同努力的结果,跟在蓝杰一样,需要通力合作,无奈我还算低调,有什么问题,轻易不会问别人,这大概是在小时候留下的病根!令人欣慰的是,打完球回来之后,并没有首先洗澡,而是又把我的聊天室代码琢磨了一遍,伴随着汗臭味,一切阻碍就这么豁然开朗了,这也算是做学问吧!也许有的时候,我们需要的只是一个好心情,一个好的心态!!!!

       现在我的小小聊天室,具体分析如下:

 

      首先我们需要先写一个服务器的界面类,在这个类里面,主要有创建服务器和发送服务器消息两个按钮,而服务器的功能有能将所有客户端的消息发给每一个在线用户,也可以在服务器的界面显示每一个客户端的发送的消息。该界面类创建代码如下

package 多人聊天室;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class MainServer {
		
	
		public void ShowUI(){
			JFrame jf=new JFrame();
			jf.setTitle("多人聊天室");
			jf.setSize(600,500);
			jf.setLayout(new FlowLayout());
			jf.setDefaultCloseOperation(3);
			JButton jb=new JButton("创建");
			final JTextField jte=new JTextField(4);
			JButton jb1=new JButton("发送");
			final JTextField jte1=new JTextField(30);
			final JTextArea jta=new JTextArea(20,50);
			jf.add(jb);
			jf.add(jte);
			jf.add(jb1);
			jf.add(jte1);
			jf.add(jta);
			
			ActionListener al=(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					String s=e.getActionCommand();
					if(s.equals("创建")){
						String ss=jte.getText();						
						int i=Integer.parseInt(ss);
						Chatserver cs=new Chatserver(i,jta);						
						cs.start();
					}
					//将服务器消息发给每个人
					if(s.equals("发送")){
						String msg=jte1.getText();
						ChatTools.castMsg(msg);
						jta.append("服务器说:"+msg+"\r\n");
						jte1.setText("");
					}
			}
			});
			jb.addActionListener(al);
			jb1.addActionListener(al);			
			jf.setVisible(true);
		}
		public static void main(String[] args){
			MainServer ms=new MainServer();
			ms.ShowUI();
		}
		}

 

 

 

        这简单的服务器界面只有两个按钮,按钮之一便是创建按钮!创建按钮,顾名思义便是创建一个服务器,等待客户端来连接,在该监听器中我使用的是内部类,在创建按钮后的 TextFiel 中输入端口号后,当该按钮被点击时,指定端口号的服务器启动了,此时服务器在等待客户机的连接,当有客户机连接了服务器之后,我们必须启动一个线程去处理该客户机对象,否则就如同一部普通手机一般,如果此时你正在通话中,那么别人是不可能在打通你的电话的,所以我们要创建一个线程类来处理连接上服务器的客户机线程对象。代码如下:

 

 

package 多人聊天室;

import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JTextArea;

public class Chatserver extends Thread{
		private boolean running=true;
		private int port;
		private JTextArea jta;
		
		public Chatserver(int port,JTextArea jta){
			this.port=port;
			this.jta=jta;
		}
	
		public void run(){
				setUpServer(port);
		}
			//在指定端口上创建一个服务器
	public void setUpServer(int port){
		try{
			//建立绑定在指定端口上的服务器对象
			ServerSocket ss=new ServerSocket(port);
			System.out.println("服务器创建成功");
			//等待客户机连接,并设置成循环等待状态
		while(running){				
				Socket client=ss.accept();
				System.out.println("欢迎进入我的服务器");
				//启动一个线程去处理该对象
				ServerThread st=new ServerThread(client,jta);
				st.start();
				ChatTools.add(st);
			}
		}catch(Exception ef){
			ef.printStackTrace();
		}
	}
}

	

 

 

 

而每一个客户端在服务器中都会拥有一个相应的处理客户端链接的方法,所以我有创建了一个线程类,在该类中得到了服务器的Socket的输入输出流。构造了一个该类的方法,用于传值;又定义了客户机一旦进入服务器的处理方法,在该方法中我们可以读取客户机发来的消息,并将该消息,群发给每一个在线的用户,还可以群发服务器自己的消息,然后并将该方法放在线程的run方法中即可。具体代码如下:

 

package 多人聊天室;


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JTextArea;

public class ServerThread extends Thread{
			private Socket client;//线程中处理的客户对象
			private OutputStream out;//输出流
			private JTextArea jta;
			//创建线程对象时要传入他要处理的连接对象
	public ServerThread(Socket client,JTextArea jta){
			this.client=client;		
			this.jta=jta;
			}
	
//			//将发送消息的代码包装到一个方法中
//	public void sendMs(String msg){
//		System.out.println("send--->"+msg);
//			try{
//				msg+="\r\n";
//				out.write(msg.getBytes());
//				//强制输出
//				out.flush();		
//			}catch(Exception ef){}
//}	
	
	public void run(){
		//在线程中 调用处理链接的方法
		processChat(this.client);
	}
	
	
	//处理客户机进入的连接对象
	public void processChat(Socket client){
		try{		
			InputStream ins=client.getInputStream();
			out=client.getOutputStream();
			//将输入流装为可以读一行字符串,也就是以\r\n结尾的字符串
			out.write( ("欢迎进入服务器\r\n").getBytes() );			
			BufferedReader brd=new BufferedReader(new InputStreamReader(ins));
			String input=brd.readLine();//一行一行读取客户机发来的消息		
			while(!"bye".equals(input)){
				System.out.println("服务器收到的是"+input);
				jta.append("客户说:"+input+"\r\n");				
				//读到一条消息就把他发给其他客户机
				ChatTools.castMsg(input);
				input=brd.readLine();//读取下一条
			}
			}catch(Exception ef){
			ef.printStackTrace();
			}
	}
}

 

 

而为了能实现消息群发的功能,并且获取当前在线的人数,我还建了一个类,在类中引用java提供的队列,当每进入一个客户机时,我们便将该客户机存入队列中,并且输出当前的在线人数,并在之后定义了一个消息群发的功能!代码如下

package 多人聊天室;

import java.util.ArrayList;
import java.util.List;


public class ChatTools {
		//保存处理线程的队列对象
	private static List<ServerThread> list=new ArrayList();
	
	private ChatTools(){
		
	}//不需要创建引类对象,构造器则私有
	//取得保存保存处理线程对象的队列
	public static List<ServerThread> getAllthread(){
		return list;
	}
		//将一个客户对应的处理线程对象加入到队列中 
	public static void add(ServerThread st){
		//通知有人上线了
		castMsg("我在线上!!目前在线人数"+(list.size()+1));
		list.add(st);
}	
		//将一个消息发送给所有人
	public static void castMsg(String str){		
		for(int i=0;i<list.size();i++){			
			ServerThread st=list.get(i);
			st.sendMs(i+"说:"+str);
		}
	}
}

 

 

 

这样一来,创建服务器并简单实现界面化的工作便完成,接下来我们还要给客户端也实现相应功能和界面化。

无可厚非,我们需要先写一个界面类。该界面能实现对服务器的连接以及将自己写的消息发送给服务器,再由服务器转发给所有在线的用户。代码如下:

 

 


package 多人聊天室客户端;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import 多人聊天室.MainServer;

public class Mainchat {
	private MainchatThread mt;
	
	public void ShowUI(){
		
		JFrame jf=new JFrame();
		jf.setTitle("客户端");
		jf.setSize(500,500);
		jf.setLocation(400, 300);
		jf.setLayout(new FlowLayout());
		jf.setDefaultCloseOperation(3);
		JButton jb=new JButton("连接服务器");
						
		JButton jb1=new JButton("发送");
		final JTextField jte1=new JTextField(30);
		final JTextArea jta=new JTextArea(20,40);
		jf.add(jb);
		jf.add(jb1);
		jf.add(jte1);
		jf.add(jta);
		ActionListener al=(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				String s=e.getActionCommand();
				if(s.equals("连接服务器")){
					try {		
					 mt=new MainchatThread("localhost",9090,jta);	
					 if(mt.runing()){
						 mt.start();						 
					 }
					} catch (Exception e1) {					
						e1.printStackTrace();
					}						
				}
				//将消息发给别人
				if(s.equals("发送")){
					String msg=jte1.getText();
					jta.append("我说:"+msg+"\r\n");					
					mt.sendMsg(msg);
					jte1.setText("");
				}
		}
		});
		jb.addActionListener(al);
		jb1.addActionListener(al);			
		jf.setVisible(true);
	}

	public static void main(String[] args){
		Mainchat ms=new Mainchat();								
		ms.ShowUI();
	}
	
}

 

 

另外,同样我们也需要定义一个线程,来读取从服务器获得消息,当我们的客户端连接成功后,而在该类中我还定义了读取的方法,并将其输出在界面上,具体代码如下:

 

package 多人聊天室客户端;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JTextArea;


public class MainchatThread extends Thread{
	private OutputStream out;
	private BufferedReader brd;	
	private Socket socket;
	private int port;
	private String ip;
	private JTextArea jta;


	public MainchatThread(String ip,int port,JTextArea jta){
		this.jta=jta;
		this.ip=ip;
		this.port=port;
		
	}

	public boolean runing(){
		try{
		Socket socket=new Socket(this.ip,this.port);		
		System.out.println("连接成功");
		InputStream ins =socket.getInputStream();//得到输入输出流对象
		out=socket.getOutputStream();
		brd=new BufferedReader(new InputStreamReader(ins));//读取一行字符串		
		return true;
		}catch (Exception e){
			e.printStackTrace();
		}return false;
		}
	
	
	//读取服务端信息的方法
	public void readMsg(){
		try{
			String input=brd.readLine();
			while(!"bye".equals(input)){			
			System.out.println("服务器"+input);
			jta.append(input +"\r\n");	
			System.out.println("你好");
			input=brd.readLine();
			}
		}catch(Exception ef){}
}	
	//输出信息
	public void sendMsg(String msg){
		try{
			msg+="\r\n";
			this.out.write(msg.getBytes());
			this.out.flush();
		}catch(Exception ef){}
}
	
	public void run(){
		readMsg();
}
}

 

 

 

至此,简单聊天室告了一个小段落,其实还是拥有很多值得改进的地方,比如,如何将所有用户显示在服务器上,并且能实现单独对话和删除用户的功能,当然还有客户端的登陆功能,这些事情在大的框架形成之后,想必不是难事。

 

 

今天的事,从一个方面反应了,其实并不是差在哪里,只是差在心态,当然时间也是一个很重要的不分,所谓勤能补拙,更何况我们都自认不是拙人,当然别人更不是拙人,心态和勤奋确实是两个很重要的因素,记之!!!!!!

 

5
1
分享到:
评论
9 楼 ming2281 2014-10-15  
大神,那个处理Socket的异常,要怎么处理,有什么经验吗?

我在实现聊天室的时候,各种异常处理起来真是心力交瘁...但是还是未能解决
8 楼 li184132481 2013-08-02  
fisher123 写道
LZ 可以参考 MINA 框架,吸收一下思想

netty也很不错,都是同一个作者写的。
7 楼 古尔丹之颅 2013-07-30  
前辈谬赞了!!!!    这一个月的集训才发现,要学的还很多啊,路漫漫其修远!
6 楼 alvin198761 2013-07-30  
很有前途的年轻人,只是这个包的名字 。。。
5 楼 古尔丹之颅 2013-07-29  
是,通信才学几天,java也才学2个多月,过段时间弄好了再写一篇,我自己也觉得没法看 ,额额!
4 楼 wangjunfu 2013-07-29  
你这代码写的比较雷人  输入输出流都没关闭 其他的没怎么看
3 楼 古尔丹之颅 2013-07-29  
整个暑假都没有回家,在学校附近集训,一下子学了很多东西,有点乱,所以写的东西也有点乱,见谅!!!!
2 楼 freezingsky 2013-07-29  
我只能说,这代码和我大学时随手写的太像了。。。
1 楼 fisher123 2013-07-29  
LZ 可以参考 MINA 框架,吸收一下思想

相关推荐

    《Java程序设计实训》报告 多人聊天室

    运用java程序编写聊天室,实现简单的聊天功能。它是图形界面,线程,流与文件系统等技术的综合应用。其界面主要采用了java.awt包,java.swing包等。程序实现了聊天室的基本功能,其中有: 1.启动服务器。  2.启动...

    Java写的简易聊天室

    本代码运用了Java的socket网络编程技术,diamagnetic简单易懂,还添加了注释。适合初学者学习。

    Java聊天室项目

    采用Java Socket 多线程技术编写的简单聊天室项目

    Java聊天室项目——橙汁聊天室.zip

    Java简易聊天室 具有群聊私聊等功能 支持用户列表动态更新 上传文件下载文件(使用Udp) 此项目仅用于学习参考

    JAVA聊天室项目+说明文档.zip

    JAVA聊天室项目+说明文档 可以简单使用,用于新手学习或者期末作业!

    java/jsp简单聊天室

    在文件中是本章的代码,所有代码都是以Web Project的项目管理方式存放的。...这是一个简单的聊天室,可以下载来参考做有关于聊天室的设计,也可以做为某些学校的java或者jsp的课程设计,只需导入就行。附有文档

    java socket简易聊天室

    使用java编写的类似聊天室的程序,在上次的基础上继续改进,将服务器端的IP地址写在配置文件里面,是程序的使用更加灵活,server.properties文件为配置文件,修改里面的ip地址为服务器端运行的ip地址即可使用。...

    基于Java的简易仿QQ聊天室的客户端源码+数据库sql.zip

    基于Java的简易仿QQ聊天室的客户端源码+数据库sql.zip 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、...

    基于JSP+Ajax+MyEclipse 2015 Java聊天室软件源码+说明文档.zip

    基于JSP+Ajax+MyEclipse 2015 Java聊天室软件源码+说明文档 通过本课程设计的实践及其前后的准备与总结,复习、领会、巩固和运用软件工程课堂上所学的软件开发方法和知识,以此来完成Java聊天室的分析、设计、编码、...

    java聊天室项目初学者实用版

    自已写的一个java聊天 室,实现的功能有 群聊,私聊,可以传文件,改变字体 ,截图。 是初学java写聊天室的模板,内容简单易懂, 功能全面。。。童叟无欺。

    Java简易聊天室.zip

    本项目只支持Netbean8.2以上的版本,主要采用java中的Tcp传输,多线程的知识。有什么问题后期可以继续解决。

    JAVA简单WEB聊天室项目

    可以用于 WEB项目的 基础联系。还有一些 小项目,后面继续

    Java GUI用Java实现简单聊天室的制作 项目(二)

    Java GUI用Java实现简单聊天室的制作 项目(二)

    Java聊天室的设计与实现socket 设计软件源码+WORD毕业论文文档.zip

    Java聊天室的设计与实现socket 设计软件源码+WORD毕业论文文档 Java聊天室系统主要用于实现在线聊天,基本功能包括:服务端和客户端。本系统结构如下: (1)服务端: 1、能够开启和关闭服务器 2、等待着客户端从...

    jsp制作的java聊天室程序

    java中采用jsp开发的聊天室,不是简单的一个client加一个server,项目在eclipse和myeclipse中都能运行

    Java 项目-Java聊天室程序(java).zip

    Java 项目,包含:项目源码、数据库脚本、部署说明等,该项目可以作为课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 一. 技术组成 ...

    JAVA上百实例源码以及开源项目源代码

    java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥  ...

    Java 项目-java聊天室程序(java)130226.zip

    Java 项目,包含:项目源码、数据库脚本、部署说明等,该项目可以作为课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 一. 技术组成 ...

Global site tag (gtag.js) - Google Analytics