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

Java UDP 聊天室實作指南:基於 DatagramSocket 的 DOS 版本架構設計

     編輯:Java 相關知識

專案概覽

本文記錄一個基於 UDP 協定的簡易聊天室實作,採用純文字介面(DOS/Console),適合初學者理解 Java 網路程式設計核心概念。專案包含伺服器端與多客戶端,支援使用者註冊、身分驗證、指定對象私聊與廣播訊息。

核心類別與 API

  • java.net.DatagramSocket:UDP 通訊端點
  • java.net.DatagramPacket:資料封包封裝
  • java.net.SocketAddress / InetSocketAddress:對端位址
  • java.util.Hashtable:執行緒安全的使用者資訊登記表
  • java.util.Enumeration:遍歷線上使用者
  • java.util.Scanner:主控台輸入讀取

伺服器端設計

職責

  1. 接收資料:阻塞式 receive(packet) 監聽埠口
  2. 資訊登記:首次收到封包時,以 SocketAddress 為鍵存入 Hashtable(暱稱、IP、Port)
  3. 協定解析:依約定字元(如 @REG# 註冊、@MSG# 訊息、@QUIT# 下線)分派處理
  4. 轉發/廣播:遍歷登記表,將封包逐一 send() 給各客戶端

關鍵資料結構

Hashtable<SocketAddress, UserInfo> userRegistry = new Hashtable<>();
class UserInfo {
    String nickname;
    SocketAddress address;
    long lastActiveTime;
}

訊息協定範例

指令格式說明
註冊@REG#暱稱客戶端首次送出,伺服器回覆 @ACK# 或 @NAK#
廣播@MSG#ALL#內容伺服器轉發給所有線上使用者
私聊@MSG#目標暱稱#內容伺服器查表轉發給指定對象
下線@QUIT#伺服器移除登記並廣播下線通知

客戶端設計

雙執行緒架構

  • 接收執行緒:持續 receive(),解析伺服器推送訊息並印至主控台
  • 主執行緒(發送):Scanner 讀取使用者輸入,封裝協定送出

啟動流程

  1. 建立 DatagramSocket(自動指派隨機本地埠)
  2. 送出註冊封包 @REG#暱稱 至伺服器固定 IP:Port
  3. 啟動接收執行緒
  4. 進入主迴圈讀取指令

完整程式碼骨架

Server.java 關鍵片段

public class ChatServer {
    private static final int PORT = 8888;
    private static Hashtable<InetSocketAddress, UserInfo> users = new Hashtable<>();
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(PORT);
        byte[] buf = new byte[1024];
        while (true) {
            DatagramPacket pkt = new DatagramPacket(buf, buf.length);
            socket.receive(pkt);
            String msg = new String(pkt.getData(), 0, pkt.getLength(), "UTF-8");
            handleMessage(socket, pkt.getSocketAddress(), msg);
        }
    }
    private static void handleMessage(DatagramSocket s, SocketAddress from, String msg) {
        if (msg.startsWith("@REG#")) { register(from, msg.substring(5)); }
        else if (msg.startsWith("@MSG#")) { dispatch(s, from, msg); }
        else if (msg.startsWith("@QUIT#")) { unregister(from); }
    }
    private static void broadcast(DatagramSocket s, String text, SocketAddress exclude) throws IOException {
        byte[] data = text.getBytes("UTF-8");
        for (SocketAddress addr : users.keySet()) {
            if (!addr.equals(exclude)) {
                s.send(new DatagramPacket(data, data.length, addr));
            }
        }
    }
}

Client.java 關鍵片段

public class ChatClient {
    private static final String SERVER_IP = "127.0.0.1";
    private static final int SERVER_PORT = 8888;
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        InetSocketAddress server = new InetSocketAddress(SERVER_IP, SERVER_PORT);
        // 註冊
        String nick = new Scanner(System.in).nextLine();
        send(socket, server, "@REG#" + nick);
        // 接收執行緒
        new Thread(() -> {
            byte[] buf = new byte[1024];
            while (true) {
                DatagramPacket pkt = new DatagramPacket(buf, buf.length);
                socket.receive(pkt);
                System.out.println(new String(pkt.getData(), 0, pkt.getLength(), "UTF-8"));
            }
        }).start();
        // 主迴圈發送
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            send(socket, server, "@MSG#ALL#" + line);
        }
    }
    private static void send(DatagramSocket s, InetSocketAddress to, String text) throws IOException {
        byte[] data = text.getBytes("UTF-8");
        s.send(new DatagramPacket(data, data.length, to));
    }
}

常見坑點與改進方向

  • UDP 不可靠:生產環境建議加入序號/ACK 重傳機制,或改用 TCP/WebSocket
  • NAT 穿透:跨網段需 STUN/TURN 或伺服器中繼
  • 編碼一致性:全鏈路強制 UTF-8
  • 心跳機制:定期發送 @PING# 檢測離線,避免殭屍連線
  • GUI 升級:Swing/JavaFX 包裝為視窗版,加入訊息歷史、表情符號、檔案傳輸

總結

透過 DatagramSocket 與 Hashtable 即可快速建構 UDP 聊天室雛形。專案雖簡單,卻涵蓋網路程式設計的核心要素:協定設計、並發存取、位址管理、封包收發。建議初學者先跑通 DOS 版本,再逐步引入可靠性保障與圖形介面。

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