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

基於 Java TCP 協議實現 C/S 架構局域網群聊系統

     編輯:Java 綜合教學

從零手寫一個基於 TCP 的 Java 群聊 Demo

Java java.net 包提供了 ServerSocket(服務端)與 Socket(客戶端)兩大核心類,支撐雙向流式通訊。本文通過一個完整的「客戶端-服務端」多線程Demo,演示如何實現:多用戶同時在線、消息廣播、上下線通知、簡易黑名單等核心群聊功能。代碼結構清晰,適合初學者理解網絡編程與多線程協作模式。

一、整體架構設計

  • Server:監聽固定端口(10000),accept() 阻塞等待連接,每來一個客戶端啟動一個 HandleSocket 線程處理該連接;維護一個 List<Socket> 存儲所有在線客戶端,集合操作加 synchronized 保證線程安全。
  • Client:啟動兩條線程——ClientSend(從控制台讀取輸入發送)與 ClientReceive(循環讀取服務端推送並打印),主線程不退出以保持長連接。
  • HandleSocket:單客戶端處理邏輯,負責讀取消息、廣播給其他客戶端、異常斷開時移除 Socket 並通知下線。

二、核心代碼實現

2.1 服務端主類

public class Server {
    public static void main(String[] args) throws IOException, InterruptedException {
        List<Socket> online = new ArrayList<>();
        ServerSocket server = new ServerSocket(10000);
        while (true) {
            Socket socket = server.accept();               // 阻塞等待連接
            synchronized (online) { online.add(socket); }  // 線程安全加入列表
            new HandleSocket(socket, online).start();      // 啟動處理線程
        }
    }
}

2.2 客戶端處理線程

public class HandleSocket extends Thread {
    private Socket socket;
    private List<Socket> online;

    public HandleSocket(Socket socket, List<Socket> online) {
        this.socket = socket; this.online = online;
    }

    @Override public void run() {
        String ip = socket.getInetAddress().getHostAddress();
        System.out.println(ip + " 上線了!");

        // 簡易黑名單演示
        if (ip.equals("192.168.1.117")) {
            synchronized (online) {
                sendToAll(ip + " 因違規被拉黑!");
                online.remove(socket);
            }
            return;
        }

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(socket.getInputStream(), "GBK"))) {
            String line;
            while ((line = br.readLine()) != null) {
                String msg = ip + ": " + line;
                System.out.println(msg);           // 服務端控制台顯示
                sendToAll(msg);                    // 廣播給其他客戶端
            }
        } catch (IOException e) {
            System.out.println(ip + " 下線了!");
            synchronized (online) { online.remove(socket); }
        }
    }

    /** 廣播消息給除發送者外的所有在線客戶端 */
    private void sendToAll(String msg) {
        synchronized (online) {
            for (Socket s : online) {
                if (s != socket) {
                    try { new PrintStream(s.getOutputStream()).println(msg); }
                    catch (IOException ignored) {}
                }
            }
        }
    }
}

2.3 客戶端發送/接收線程

// 發送線程
public class ClientSend extends Thread {
    private Socket socket;
    public ClientSend(Socket socket) { this.socket = socket; }
    @Override public void run() {
        try (PrintStream ps = new PrintStream(socket.getOutputStream());
             Scanner sc = new Scanner(System.in)) {
            String line;
            while ((line = sc.nextLine()) != null) ps.println(line);
        } catch (IOException e) { e.printStackTrace(); }
    }
}

// 接收線程
public class ClientReceive extends Thread {
    private Socket socket;
    public ClientReceive(Socket socket) { this.socket = socket; }
    @Override public void run() {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(socket.getInputStream()))) {
            String line;
            while ((line = br.readLine()) != null) System.out.println(line);
        } catch (Exception e) { e.printStackTrace(); }
    }
}

2.4 客戶端啟動類

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("192.168.1.188", 10000); // 修改為實際服務端 IP
        new ClientSend(socket).start();
        new ClientReceive(socket).start();
        // 主線程不退出,保持長連接
    }
}

三、運行步驟與效果驗證

  1. 先啟動 Server.main(),控制台顯示等待連接;
  2. 啟動多個 Client.main()(可在不同機器/進程),分別輸入用戶名/消息;
  3. 服務端控制台會打印 IP 上線了!、IP: 消息內容、IP 下線了!;
  4. 每個客戶端窗口都能實時看到其他人的發言與上下線通知。

四、代碼亮點與可擴展方向

  • 線程隔離:每客戶端一線程,互不阻塞;
  • 線程安全集合:synchronized(online) 保護增刪改查;
  • 編碼指定:服務端讀取指定 GBK,避免中文亂碼(客戶端默認 UTF-8 需統一);
  • 優雅關閉:捕獲 IOException 統一處理下線邏輯。

進階擴展建議:引入協議幀(如 JSON/Protobuf)區分聊天/私聊/文件/心跳;使用 NIO/Netty 替換 BIO 提升併發上限;加入用戶認證、群組管理、消息持久化、離線推送等。

五、完整項目結構

com.dragon.java.tcpchat
├── Server.java
├── HandleSocket.java
├── Client.java
├── ClientSend.java
└── ClientReceive.java

這是一個「弱小但完整」的局域網群聊原型,通過親手敲碼、跑通流程,能快速建立起「Socket 通訊 + 多線程協作 + 共享狀態同步」的核心心智模型,為後續學習 Netty、即時通訊架構打下堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved