
import java.io.*;
import java.net.*;
import java.util.*;

public class ChatRoomServer {
	private ServerSocket serverSocket;// 服务器套接字
	private HashSet<Socket> allSockets;// 客户端套接字集合

	/**
	 * 聊天室服务器的构造方法
	 */
	public ChatRoomServer() {
		try {
			serverSocket = new ServerSocket(4569);// 开启服务器4569接口
		} catch (IOException e) {
			e.printStackTrace();
		}
		allSockets = new HashSet<Socket>();// 实例化客户端套接字集合
	}

	/**
	 * 启动聊天室服务器的方法
	 */
	public void startService() throws IOException {
		while (true) {
			Socket s = serverSocket.accept();// 获得一个客户端的连接
			System.out.println("用户已进入聊天室");
			allSockets.add(s);// 将客户端连接的套接字放到集合中
			new ServerThread(s).start();// 为此客户端单独创建一个事务处理线程
		}
	}

	/**
	 * 服务器线程内部类
	 */
	private class ServerThread extends Thread {
		Socket socket; // 客户端套接字

		public ServerThread(Socket socket) {// 通过构造方法获取客户端连接
			this.socket = socket;
		}

		public void run() {
			BufferedReader br = null;
			try {
				// 将客户端套接字输入流转换为字节流读取
				br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				while (true) {// 无限循环
					String str = br.readLine();// 读取到一行之后，则赋值给字符串
					if (str.contains("%EXIT%")) {// 如果文本内容中包括"%EXIT%"
						allSockets.remove(socket);// 集合删除此客户端连接
						// 服务器向所有客户端接口发送退出通知
						sendMessageTOAllClient(str.split(":")[1] + " 用户已退出聊天室");
						socket.close();// 关闭此客户端连接
						return;// 结束循环
					}
					sendMessageTOAllClient(str);// 向所有客户端此客户端发来的文本信息
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * 发送信息给所有客服端的方法
		 * 
		 * @param message
		 *            服务器向所有客户端发送文本内容
		 */
		public void sendMessageTOAllClient(String message) throws IOException {
			for (Socket s : allSockets) {// 循环集合中所有的客户端连接
				PrintWriter pw = new PrintWriter(s.getOutputStream());// 创建输出流
				pw.println(message);// 输写入文本内容
				pw.flush();// 输出流刷新
			}
		}
	}

	public static void main(String[] args) {
		try {
			new ChatRoomServer().startService();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
