Java简易聊天室

Chat Server服务器代码片`.

// An highlighted block
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public  class ChatServer {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//构造一个端口6000的ServerSocket
		//这里构造serverSocket		 
		try(ServerSocket chat=new ServerSocket(6000)){
			SocketList list=new SocketList();
			System.out.println("聊天室启动...");
			while(true) {
				Socket connection=chat.accept();
				ThreadHander client=new ThreadHander(connection);
				Thread t=new Thread(client);
				list.addList(client);
				System.out.println(list.getList());
				t.start();
			}
			
		}catch(BindException ex) {
			System.err.println(ex.getMessage()+" 绑定端口失败!");
		}catch(SocketException ex) {
			System.err.println(ex.getMessage()+" 连接客户端失败");
		}
		catch(IOException ex) {
			System.err.println(ex.getMessage()+"测试");
		}
		
	}
}
	
//线程对象实例数组
class SocketList{
	//静态数组
	private static ArrayList<ThreadHander> clients=new ArrayList<ThreadHander>();
	//添加对象
	public void  addList(ThreadHander m) {
		clients.add(m);
	}
	//返回数组
	public ArrayList<ThreadHander> getList() {
		return clients;		
	}
	//删除对象,发生错误时,就删除发生错误的对象
	public void removeList(ThreadHander m) {
		clients.remove(m);
	}
}
		
	
//多个线程,用于连接多个客户端	
	
class ThreadHander implements Runnable{
	private Socket socket;
	private PrintWriter write;
	private BufferedReader read;
	private String name;
	private ArrayList<ThreadHander> list;
	private SocketList SL;//类变量
	private boolean Flag=true;//标志位,如果是false则表示该子线程出现错误,然后退出循环,run()方法执行完毕退出,线程结束
	ThreadHander(Socket socket){
		this.socket=socket;
	}
	
	//发送数据
	private void send(String s) throws IOException{
		write.println(s);	
		write.flush();
	}
	
	//发送数据给其他人,实质是用遍历ThreadHander数组的,使用实例的send()方法
	private void sendOther(String s) {
		// TODO Auto-generated method stub
		try {
			if(s.equals("")||s==null)
				return;
			list=SL.getList();
			for(ThreadHander th:list) {
				//System.out.println("this"+this);
				//System.out.println("th"+th);
				//如果是自己就不发送
				if(th==this)
					continue;	
				//name是客户加入时的名字
				if(s.equals("加入群聊"))
					th.send(name+s);
				else
					th.send(name+": "+s);
				System.out.println(s);
			}
			
		}catch (IOException e) {
			System.err.println(e.getMessage()+"sendOther");
			SL.removeList(this);
			Flag=false;
		}
	}
	
	
	//接受数组方法
	private String recv() {	
		String s="";
		try {			
			s=read.readLine();
			
		}catch(SocketException e){
			System.err.println(e.getMessage()+"SocketException");
			SL.removeList(this);
			Flag=false;			
		}catch(IOException e){
			System.err.println(e.getMessage()+"IOException");
			//SL.removeList(this);
			//Flag=false;	
			}	
		System.out.println(s);
		return s;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			SL=new SocketList();
			write=new PrintWriter(socket.getOutputStream());
			read=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			send("欢迎加入群聊");
			name=recv();//获取 该用户昵称
			sendOther("加入群聊");				
			while(Flag==true) {				
				sendOther(recv());
			}
			System.out.println(this+"线程连接中断,该线程结束");
		}catch(IOException ex){
			System.err.println(ex.getMessage()+"xianchengRun");
			}finally {
				try {
					socket.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		
	}

	
}

ChatClient 客户端代码:

import javax.swing.JOptionPane;
import java.net.*;
import java.io.*;

public class ChatClient {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		initClient client=new initClient();
		client.qidong();
	}
	 
}


class initClient{
	private static Socket socket;
	initClient(){
		socket=new Socket();
	}
	 void qidong() {
		
		SocketAddress chatAddress=new InetSocketAddress("localhost",6000);
		try {		
			//连接服务器
			socket.connect(chatAddress);		
			String aName=JOptionPane.showInputDialog("请输入你的名字");
			ThreadRecv recv=new ThreadRecv(socket);
			ThreadSend send=new ThreadSend(socket,aName);
			Thread re=new Thread(recv);
			Thread se=new Thread(send);
			re.start();
			se.start();
			
		}catch(UnknownHostException ex){
			System.err.println("I can't find the host");
			
		}catch(SocketException ex) {
			System.err.println("Could not connect to the host");
			try {
				socket.close();
				System.out.println("socket资源关闭");
			}catch(IOException ex1) {
				ex1.printStackTrace();				
		}
			
		}catch(IOException ex) {
			System.err.println("连接断开失败");
		}
			
	}
	
}


//接收线程
class ThreadRecv implements Runnable{
	private Socket socket;
	private BufferedReader in;//读入流
	ThreadRecv(Socket aSocket){
		socket=aSocket;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			String string;
			in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			while(true) {
				string=in.readLine();	
				System.out.println(string);
			}
		
		}catch(SocketException ex) {
			System.err.println("连接服务器失败!!!");	
			try {
					socket.close();
					System.out.println("socket资源关闭\n退出程序!");
					//终止程序
					System.exit(0);								
				}catch(IOException ex1) {
					ex1.printStackTrace();				
			}
		}
		catch(IOException ex) {
			System.err.println("error错误!!!");
		}
		
	}
}


//发送线程
class ThreadSend implements Runnable{
	private Socket socket;
	private PrintWriter out;//输出流
	private BufferedReader sin;
	private String name;//发送自己的名字
	ThreadSend(Socket aSocket,String aName){
		socket=aSocket;
		name=aName;
	}	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {		
			out=new PrintWriter(socket.getOutputStream());//获取输出流
			sin=new BufferedReader(new InputStreamReader(System.in));		
			out.println(name);
			out.flush();
			while(!socket.isClosed()) {
				System.out.print("请输入内容:");
				String s=sin.readLine();
				out.println(s);
				out.flush();
			}
		}catch(IOException ex) {
			System.err.println("输出失败");
		}
	}
}

cmd执行Java程序,以管理员执行cmd
图片: 启动多个客户端程序,启动多个cmd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值