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

J2ME UDP 協定程式設計實戰:DatagramConnection 與 Datagram 完整客戶端/伺服器範例

     編輯:Java 程式設計入門

前言

GCF 提供 DatagramConnection、Datagram 支援 UDP 開發。MIDP 2.0 新增 UDPDatagramConnection (含 getLocalAddress/getLocalPort)。UDP 不可靠,需可靠傳輸請用 Socket (TCP)。注意:除 HTTP 外,其他連接協定非 MIDP 強制實作,使用前必查裝置文件。

一、連線 URL 格式

  • 客戶端模式:datagram://host:port (如 datagram://localhost:5555)
  • 伺服器模式:datagram://:port (本地監聽指定埠)

二、發送端實作 (Sender 執行緒)

public class Sender extends Thread {
    private DatagramConnection dc;
    private String address, message;

    public Sender(DatagramConnection dc) { this.dc = dc; start(); }

    public synchronized void send(String addr, String msg) {
        address = addr; message = msg; notify();
    }

    public void run() {
        while (true) {
            synchronized (this) {
                if (message == null) { try { wait(); } catch (InterruptedException ignored) {} }
            }
            try {
                byte[] bytes = message.getBytes();
                Datagram dg = (address == null) ?
                    dc.newDatagram(bytes, bytes.length) :
                    dc.newDatagram(bytes, bytes.length, address);
                dc.send(dg);
            } catch (Exception e) { e.printStackTrace(); }
            message = null;
        }
    }
}

三、伺服器端實作

public class Server implements Runnable, CommandListener {
    private DatagramMIDlet parent;
    private Display display;
    private Form form;
    private StringItem status;
    private TextField input;
    private Command sendCmd;
    private Sender sender;
    private String clientAddr;

    public Server(DatagramMIDlet m) { /* UI 初始化 */ }

    public void start() { new Thread(this).start(); }

    public void run() {
        try {
            status.setText("Waiting for connection");
            DatagramConnection dc = (DatagramConnection) Connector.open("datagram://:5555");
            sender = new Sender(dc);
            while (true) {
                Datagram dg = dc.newDatagram(100);
                dc.receive(dg);
                clientAddr = dg.getAddress();
                status.setText("Received: " + new String(dg.getData(), 0, dg.getLength()));
            }
        } catch (IOException e) { /* 埠佔用提示 */ }
    }

    public void commandAction(Command c, Displayable s) {
        if (c == sendCmd && !parent.isPaused()) {
            if (clientAddr == null) status.setText("No destination");
            else sender.send(clientAddr, input.getString());
        }
    }
}

四、客戶端實作

public class Client implements Runnable, CommandListener {
    private DatagramMIDlet parent;
    private Display display;
    private Form form;
    private StringItem status;
    private TextField input;
    private Command sendCmd;
    private DatagramConnection dc;

    public Client(DatagramMIDlet m) { /* UI 初始化 */ }

    public void start() {
        try {
            dc = (DatagramConnection) Connector.open("datagram://localhost:5555");
            new Thread(this).start();
        } catch (IOException e) { /* 錯誤處理 */ }
    }

    public void run() {
        while (true) {
            try {
                Datagram dg = dc.newDatagram(100);
                dc.receive(dg);
                status.setText("Server: " + new String(dg.getData(), 0, dg.getLength()));
            } catch (IOException e) { break; }
        }
    }

    public void commandAction(Command c, Displayable s) {
        if (c == sendCmd) {
            try {
                byte[] bytes = input.getString().getBytes();
                Datagram dg = dc.newDatagram(bytes, bytes.length);
                dc.send(dg);
            } catch (IOException e) { status.setText("Send failed"); }
        }
    }
}

五、關鍵注意事項

  • 網路操作**必須在背景執行緒**執行,避免阻塞 UI。
  • UDP 無連線狀態,伺服器需記錄客戶端位址才能回覆。
  • 資料封包大小建議 ≤ MTU (通常 1500 bytes) 避免分片。
  • 實作可靠傳輸需自行加入序號、ACK、重傳機制,或改用 TCP Socket。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved