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

Java 實作 UDP 協定簡易聊天室

     編輯:Java 相關知識

前言

近期閒暇之餘,決定重溫 Java 網路程式設計的基礎,便動手實作了一個基於 UDP 協定的簡易聊天室。雖然現代開發較少直接操作 Socket,但這類練習有助於鞏固網路通訊的核心概念。本文將完整呈現從伺服端、客戶端到訊息實體類的程式碼結構,並附上測試範例。

系統架構與功能概覽

這個聊天室支援多房間機制:使用者輸入房間 ID 與暱稱即可加入。同一房間內的訊息會即時廣播給所有成員,不同房間則互不干擾。執行畫面中,「聊天室001」的小紅與小綠正常對話,而「聊天室002」的小黑則獨自一人,完美展示房間隔離效果。

核心模組實作

1. 訊息伺服器

伺服器職責單純明確:

  • 註冊客戶端資訊(房間 ID、客戶端物件)
  • 建立 DatagramSocket 監聽 UDP 封包
  • 解析 JSON 訊息,依房間 ID 廣播給對應客戶端
package com.tsr.simplechat.receive_server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import com.google.gson.Gson;
import com.tsr.simplechat.bean.MessageEntity;
import com.tsr.simplechat.client.ChatClient;

public class ChatServer extends Thread {
    private static final int PORT = 10000;
    private static DatagramSocket server = null;
    private static HashMap<String, ArrayList<ChatClient>> groups = new HashMap<>();

    public ChatServer() {
        try {
            server = new DatagramSocket(PORT);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public static void logInGroup(String groupID, ChatClient client) {
        ArrayList<ChatClient> clients = groups.get(groupID);
        if (clients == null) {
            clients = new ArrayList<>();
        }
        clients.add(client);
        groups.put(groupID, clients);
    }

    @Override
    public void run() {
        while (true) {
            receiveMessage();
        }
    }

    private void receiveMessage() {
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);
        while (true) {
            try {
                server.receive(packet);
            } catch (IOException e) {
                e.printStackTrace();
            }
            String content = new String(packet.getData(), 0, packet.getLength());
            Gson gson = new Gson();
            MessageEntity me = gson.fromJson(content, MessageEntity.class);
            ArrayList<ChatClient> clients = groups.get(me.getGroupId());
            if (clients != null) {
                for (ChatClient client : clients) {
                    client.pushBackMessage(me);
                }
            }
        }
    }
}

2. 客戶端程式

採用 AWT 建構簡易 GUI,包含訊息顯示區、輸入框與發送按鈕。核心邏輯:

  • 啟動時向伺服器註冊(房間 ID、暱稱)
  • 建立發送用 DatagramSocket
  • 將輸入文字封裝為 JSON 經 UDP 發送
  • 提供回調方法 pushBackMessage 供伺服器推送訊息更新 UI
package com.tsr.simplechat.client;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import com.tsr.simplechat.bean.MessageEntity;
import com.tsr.simplechat.receive_server.ChatServer;

public class ChatClient extends Frame {
    private static final long serialVersionUID = 1L;
    private String groupID, clientName;
    private DatagramSocket msg_send;
    private final int PORT = 10000;
    private InetAddress ip;
    private TextField tf = new TextField(20);
    private TextArea ta = new TextArea();
    private Button send = new Button("send");

    public ChatClient(String groupID, String clientName) {
        super("聊天室:" + groupID + "/" + clientName);
        this.clientName = clientName;
        this.groupID = groupID;
        add("North", tf);
        add("Center", ta);
        add("South", send);
        setSize(250, 250);
        show();
        init();
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                msg_send.close();
                dispose();
                System.exit(0);
            }
        });
    }

    private void init() {
        ChatServer.logInGroup(groupID, this);
        try {
            msg_send = new DatagramSocket();
            ip = InetAddress.getByName("127.0.0.1");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean action(Event evt, Object arg) {
        if (evt.target.equals(send)) {
            try {
                String content = tf.getText();
                send_message(content);
                tf.setText("");
            } catch (Exception ioe) {
                System.out.print(ioe.getMessage());
            }
        }
        return true;
    }

    private void send_message(String content) {
        String message = messageFormat(content);
        byte[] buf = message.getBytes();
        DatagramPacket packet = new DatagramPacket(buf, buf.length, ip, PORT);
        try {
            msg_send.send(packet);
        } catch (IOException e) {
            System.out.println("IO 異常");
        }
    }

    private String messageFormat(String content) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("{\"groupId\":\"").append(groupID).append("\",");
        buffer.append("\"userName\":\"").append(clientName).append("\",");
        buffer.append("\"text\":\"").append(content).append("\"}");
        return buffer.toString();
    }

    public void pushBackMessage(MessageEntity me) {
        ta.append(me.getUserName() + ":" + me.getText() + "\n");
    }
}

3. 訊息實體類

單純的 POJO,配合 Gson 進行 JSON 序列化/反序列化。

package com.tsr.simplechat.bean;

public class MessageEntity {
    private String groupId;
    private String userName;
    private String text;
    // Getter/Setter 略
}

4. 測試啟動類

一鍵啟動伺服器與三個客戶端,驗證多房間隔離功能。

import com.tsr.simplechat.client.ChatClient;
import com.tsr.simplechat.receive_server.ChatServer;

public class Test {
    public static void main(String[] args) {
        ChatServer server = new ChatServer();
        server.start();
        new ChatClient("001", "小紅");
        new ChatClient("001", "小綠");
        new ChatClient("002", "小黑");
    }
}

總結

此範例雖簡單,卻涵蓋 UDP 通訊、多執行緒、JSON 序列化、GUI 事件處理等核心技術。適合初學者理解 Java 網路程式基礎,也可作為擴充功能(如私聊、檔案傳輸)的起點。

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