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

Java 基於 TCP 的局域網多人聊天室 (C/S 架構)

     編輯:Java 相關知識

架構概覽

  • Server:ServerSocket 監聽端口,維護 List<Socket> 所有客戶端連接,每連接啟動 HandleSocket 線程處理收發。
  • Client:Socket 連接服務器,雙線程:ClientSend 讀控制台發送,ClientReceive 讀網絡流打印。

服務端代碼

public class Server {
    public static void main(String[] args) throws IOException {
        List<Socket> clients = new ArrayList<>();
        ServerSocket server = new ServerSocket(10000);
        while (true) {
            Socket socket = server.accept();
            synchronized (clients) { clients.add(socket); }
            new HandleSocket(socket, clients).start();
        }
    }
}

class HandleSocket extends Thread {
    private Socket socket; private List<Socket> list;
    public HandleSocket(Socket s, List<Socket> l) { this.socket = s; this.list = l; }

    public void run() {
        String ip = socket.getInetAddress().getHostAddress();
        System.out.println(ip + " 上線");
        if ("192.168.1.117".equals(ip)) { // 黑名單示例
            synchronized (list) { sendAll(ip + " 被拉黑"); list.remove(socket); }
            return;
        }
        try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"))) {
            String msg;
            while ((msg = br.readLine()) != null) {
                String broadcast = ip + ":" + msg;
                System.out.println(broadcast);
                sendAll(broadcast);
            }
        } catch (IOException e) {
            System.out.println(ip + " 下線");
            synchronized (list) { list.remove(socket); }
        }
    }

    private void sendAll(String msg) {
        synchronized (list) {
            for (Socket s : list) if (s != socket) {
                try { new PrintStream(s.getOutputStream()).println(msg); }
                catch (IOException ignored) {}
            }
        }
    }
}

客戶端代碼

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("192.168.1.188", 10000);
        new ClientSend(socket).start();
        new ClientReceive(socket).start();
    }
}

class ClientSend extends Thread {
    private Socket socket;
    public ClientSend(Socket s) { this.socket = s; }
    public void run() {
        try (PrintStream ps = new PrintStream(socket.getOutputStream());
             Scanner sc = new Scanner(System.in)) {
            while (sc.hasNextLine()) ps.println(sc.nextLine());
        } catch (IOException ignored) {}
    }
}

class ClientReceive extends Thread {
    private Socket socket;
    public ClientReceive(Socket s) { this.socket = s; }
    public void run() {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
            String line;
            while ((line = br.readLine()) != null) System.out.println(line);
        } catch (IOException ignored) {}
    }
}

運行順序

  1. 先啟動 Server.main。
  2. 再啟動多個 Client.main(修改 IP 為服務器地址)。
  3. 控制台輸入即發送,所有客戶端同步顯示。

改進方向

  • 用戶名登錄、私聊、表情、文件傳輸。
  • Netty 重寫實現高併發、心跳、編解碼器。
  • GUI 界面(Swing/JavaFX)替換控制台。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved