JavaSE使用socket與線程實現控制檯版的聊天室功能

服務器server端:

	private ServerSocket server;// 創建了ServerSocket對象
	// 存放所有客戶端輸出流的集合,並初始化
	private List<PrintWriter> allOut = new ArrayList<PrintWriter>();

	// 向集合中添加元素
	private synchronized void addOut(PrintWriter out) {
		allOut.add(out);
	}

	// 從集合中刪除元素
	private synchronized void removeOut(PrintWriter out) {
		allOut.remove(out);
	}

	// 遍歷集合向所有的客戶端發送信息
	private synchronized void sendMessage(String msg) {
		for (PrintWriter out : allOut) {
			out.println(msg);
		}

	}

	/**
	 * 構造方法,用來初始化ServerSocket
	 * 
	 * @throws IOException
	 */
	public Server() throws IOException {
		try {
			server = new ServerSocket(8088);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
	}

	public void start() throws IOException {
		while (true) {
			try {
				Socket socket = server.accept();
				/**
				 * 當一個客戶端連接後,應該啓動一個線程,來負責與客戶端的交互 這樣才能循環接待不同的客戶端
				 */
				ClientHandler hander = new ClientHandler(socket);
				Thread thread = new Thread(hander);
				// 啓動線程
				thread.start();
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
		}
	}

	public static void main(String[] args) {
		Server server = null;
		try {
			server = new Server();
			server.start();
		} catch (IOException e) {
			System.out.println("服務器啓動失敗");
		}
	}

	/**
	 * 啓動線程的成員內部類
	 * 
	 * @author Admin
	 * 
	 */

	class ClientHandler implements Runnable {
		private Socket socket;

		public ClientHandler(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			PrintWriter writer = null;
			try {
				// 向客戶端發送信息
				writer = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream(), "utf-8"), true);
				addOut(writer);
				// 讀取客戶端的信息
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(socket.getInputStream(), "utf-8"));
				String msg = null;

				while ((msg = reader.readLine()) != null) {
					// 將客戶端發送過來的信息轉發給客戶端
					sendMessage(msg);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				// 處理客戶端斷開連接後的工作
				// 將客戶端的輸出流從集合中移除
				removeOut(writer);
			}
		}
	}
客戶端client端:

	// 創建與服務端通訊的Socket
	private Socket socket;

	public Client() throws IOException {
		try {
			socket = new Socket("localhost", 8088);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		}
	}

	// 客戶端開始工作的方法
	public void start() {
		// 啓動線程,用於讀取服務端發送過來的信息
		ServerHandler handler = new ServerHandler();
		Thread thread = new Thread(handler);
		// 啓動線程
		thread.start();
		/**
		 * 循環從控制檯輸入信息發送至服務端
		 */
		Scanner sca = new Scanner(System.in);
		try {
			PrintWriter writer = new PrintWriter(new OutputStreamWriter(
					socket.getOutputStream(), "utf-8"), true);
			String msg = null;
			while (true) {
				msg = sca.nextLine();
				writer.println(msg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Client c = null;
		try {
			c = new Client();
			c.start();
		} catch (IOException e) {
			System.out.println("連接失敗");
		}
	}

	// 讀取服務端發送過來的信息的線程
	class ServerHandler implements Runnable {

		@Override
		public void run() {
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(socket.getInputStream(), "utf-8"));
				String msg = null;
				while ((msg = reader.readLine()) != null) {
					System.out.println(msg);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章