首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java TCP Socket 多執行緒聊天室完整實作

     編輯:Java 相關知識

架構設計

  • Server:監聽端口,接受客戶端連線,為每個連線建立獨立執行緒處理收發訊息,維護線程安全的客戶端列表用於廣播。
  • Client:連線伺服器,啟動兩條執行緒:一條負責從控制台讀取輸入並發送,一條負責接收伺服器廣播訊息並列印。

Server 端核心代碼

public class TCPServer {
    private static final int PORT = 8888;
    private final ServerSocket serverSocket;
    private final List clients = new CopyOnWriteArrayList<>(); // 線程安全列表
    private final ExecutorService executor = Executors.newCachedThreadPool();

    public TCPServer() throws IOException {
        serverSocket = new ServerSocket(PORT);
        System.out.println("伺服器啟動,監聽端口:" + PORT);
        while (true) {
            Socket client = serverSocket.accept();
            clients.add(client);
            executor.execute(new ClientHandler(client));
        }
    }

    private class ClientHandler implements Runnable {
        private final Socket socket;
        private final BufferedReader in;
        private final PrintWriter out;

        ClientHandler(Socket socket) throws IOException {
            this.socket = socket;
            this.in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
            this.out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
            broadcast("用戶 [" + socket.getInetAddress() + "] 進入聊天室,當前人數:" + clients.size());
        }

        public void run() {
            try {
                String msg;
                while ((msg = in.readLine()) != null) {
                    if ("exit".equalsIgnoreCase(msg.trim())) break;
                    broadcast(socket.getInetAddress() + ": " + msg);
                }
            } catch (IOException e) {
                // 忽略連線中斷異常
            } finally {
                clients.remove(socket);
                closeQuietly(socket, in, out);
                broadcast("用戶 [" + socket.getInetAddress() + "] 離開,當前人數:" + clients.size());
            }
        }

        private void broadcast(String msg) {
            for (Socket client : clients) {
                try {
                    new PrintWriter(new OutputStreamWriter(client.getOutputStream(), "UTF-8"), true).println(msg);
                } catch (IOException ignored) {}
            }
        }
    }
}

Client 端核心代碼

public class TCPClient {
    private static final String HOST = "127.0.0.1";
    private static final int PORT = 8888;

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(HOST, PORT);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);

        // 接收訊息執行緒
        new Thread(() -> {
            try {
                String msg;
                while ((msg = in.readLine()) != null) System.out.println(msg);
            } catch (IOException ignored) {}
        }).start();

        // 發送訊息主迴圈
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        String input;
        while ((input = console.readLine()) != null) {
            out.println(input);
            if ("exit".equalsIgnoreCase(input.trim())) break;
        }
        socket.close();
    }
}

關鍵改進點

  • 使用 CopyOnWriteArrayList 替代 ArrayList + 同步,簡化併發控制。
  • 統一採用 UTF-8 編碼,避免中文亂碼。
  • 資源關閉採用 try-with-resources 或輔助方法,防止洩漏。
  • 執行緒池替代手動建立執行緒,提升擴展性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved