聊天室代码

  • 客户端代码
package chat.room.server;
import java.net.Socket;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
//客户端读取服务器端信息的线程
class ClientReadServer implements Runnable{
	private Socket socket;
	public ClientReadServer(Socket socket){
		this.socket = socket;
	}
	public void run(){
		//获取服务器端输入流
		Scanner scanner;
		try {
			scanner = new Scanner(socket.getInputStream());
			while(scanner.hasNext()){
				System.out.println(scanner.next());
			}
			scanner.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
//客户端向服务器发送信息的线程
class ClientSendServer implements Runnable{
	private Socket socket;
	public ClientSendServer(Socket socket){
		this.socket = socket;
	}
	public void run(){
		try {
			//获取服务器端的输出流
			PrintStream printStream = new PrintStream(socket.getOutputStream());
			//从键盘输入信息
			Scanner scanner = new Scanner(System.in);
			while(true){
				String msg = null;
				if(scanner.hasNext()){
					msg = scanner.next();
					printStream.println(msg);
				}
				if(msg.equals("exit")){
					scanner.close();
					printStream.close();
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
public class MultiClient{
	public static void main(String[] args) throws IOException{
		//客户端连接服务器端,返回套接字Socket对象
		Socket socket = new Socket("127.0.0.1",6666);
		//创建读取服务器端信息的线程和发送服务器端信息的线程
		Thread read = new Thread(new ClientReadServer(socket));
		Thread send = new Thread(new ClientSendServer(socket));
		//启动线程
		read.start();
		send.start();
	}
}
  • 服务器端代码
package chat.room.server;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.PrintStream;
import java.io.IOException;
class Server implements Runnable{
	private static Map map = new ConcurrentHashMap();
	private Socket socket;
	public Server(Socket socket){
		this.socket = socket;
	}
	public void run(){
		//获取客户端的输入流
		try{
			Scanner scanner = new Scanner(socket.getInputStream());
			String msg = null;
			while(true){
				if(scanner.hasNextLine()){
					//处理客户端输入的字符串
					msg = scanner.nextLine();
					Pattern pattern = Pattern.compile("\r");
					Matcher matcher = pattern.matcher(msg);
					msg = matcher.replaceAll("");
					//1.注册用户流程,注册用户格式为:userName:用户名
					if(msg.startsWith("userName:")){
						//将用户名保存在userName中
						String userName = msg.split("\\:")[1];
						//注册用户
						userRegist(userName,socket);
						continue;
					}
					//2.群聊信息流程,群聊的格式为:G:群聊信息
					else if(msg.startsWith("G:")){
						//必须先注册才可以
						firstStep(socket);
						//保存群聊信息
						String str = msg.split("\\:")[1];
						//发送群聊信息
						groupChat(socket,str);
						continue;
					}
					//3.私聊信息流程,私聊的格式为:P:userName-私聊信息
					else if(msg.startsWith("P:")&&msg.contains("-")){
						//必须先注册才可以
						firstStep(socket);
						//保存需要私聊的用户名
						String userName = msg.split("\\:")[1].split("-")[0];
						//保存私聊的信息
						String str = msg.split("\\:")[1].split("-")[1];
						//发送私聊信息
						privateChat(socket,userName,str);
						continue;
					}
					//4.用户退出流程,用户退出格式为:包含exit
					else if(msg.contains("exit")){
						//必须先注册才可以
						firstStep(socket);
						userExit(socket);
						continue;
					}
					//其他输入格式均错误
					else{
						PrintStream printStream = new PrintStream(socket.getOutputStream());
						printStream.println("输入格式错误,请按照以下格式输入");
						printStream.println("注册用户格式:[userName:用户名]");
						printStream.println("群聊格式:[G:群聊信息]");
						printStream.println("私聊格式:[P:userName-私聊信息]");
						printStream.println("用户退出格式[包含exit即可]");
						continue;
					}
					}
			}
				}catch(IOException e){
					e.printStackTrace();
				}
			} 				
private void firstStep(Socket socket) throws IOException {
	        Set> set=map.entrySet();
	        for(Map.Entry entry:set){
	            if(entry.getValue().equals(socket)){
	                if(entry.getKey()==null){
	                    PrintStream printStream=new PrintStream(socket.getOutputStream());
	                    printStream.println("请先进行注册操作!");
	                    printStream.println("注册格式为:[userName:用户名]");
	                }
	            }
	        }
	    }
private void userRegist(String userName,Socket socket){
	map.put(userName,socket);
	System.out.println("[用户名为"+userName+"][客户端为"+socket+"]上线了!");
	System.out.println("当前在线人数为:"+map.size()+"人");
}
private void userExit(Socket socket){
	//利用socket取得对应的key值
	String userName = null;
	for(String key:map.keySet()){
		if(map.get(key).equals(socket)){
			userName = key;
			break;
		}		
	}
	//将userName,Socket元素从map集合中删除
	map.remove(userName,socket);
	//提醒服务器客户端已下线
	System.out.println("用户:"+userName+"已下线");
}
private void privateChat(Socket socket,String userName,String msg) throws IOException{
	//取得当前客户端的用户名
	String curUser = null;
	Set> set=map.entrySet();
	for(Map.Entry entry:set){
		if(entry.getValue().equals(socket)){
			curUser = entry.getKey();
			break;
		}
	}
	//取得私聊用户名对应的客户端
	Socket client = map.get(userName);
	//获取私聊客户端的输出流,将私聊信息发送到指定客户端
	PrintStream printStream = new PrintStream(client.getOutputStream());
	printStream.println(curUser+"私聊说:"+msg);
}
private void groupChat(Socket socket,String msg) throws IOException{
	//将Map集合转换为Set集合
	Set> set = map.entrySet();
	//遍历Set集合找到发起群聊信息的用户
	String userName = null;
	for(Map.Entry entry:set){
		if(entry.getValue().equals(socket)){
			userName = entry.getKey();
			break;
		}
	}
	//遍历Set集合将群聊信息发给每一个客户端
	for(Map.Entry entry:set){
		//取得客户端的Socket对象
		Socket client = entry.getValue();
		//取得client客户端的输出流
		PrintStream printStream = new PrintStream(client.getOutputStream());
		printStream.println(userName+"群聊说:"+msg);
	}
}
}
public class MultiServer{
	public static void main(String[] args){
		try{
		//1.创建服务器端的ServerSocket对象,等待客户端连接
		ServerSocket serverSocket = new ServerSocket(6666);
		//2.创建线程池,从而可以处理多个客户端
		ExecutorService executorService = Executors.newFixedThreadPool(20);
		for(int i=0;i<20;i++){
			System.out.println("欢迎来到我的聊天室……");
			//3.监听客户端
			Socket socket = serverSocket.accept();
			System.out.println("有新的朋友加入……");
			//启动线程
			executorService.execute(new Server(socket));
		}
		//关闭线程池
		executorService.shutdown();
		//关闭服务器
		serverSocket.close();
	} catch(IOException e){
		e.printStackTrace();
	}
}
}

 

你可能感兴趣的:(JavaSE)