嵌入式設備時代的 Java 網絡編程,以 Windows CE / PocketPC 平台為例,完整展示從基礎 Socket 通訊到多層架構、RMI 分布式調用的實戰開發流程。
import java.io.*;
import java.net.*;
public class NetServer {
private ServerSocket serverSocket;
private Socket clientSocket;
public NetServer() {
try {
serverSocket = new ServerSocket(900, 200); // 埠口 900,最大佇列 200
System.out.println("Server 啟動,等待連線...");
clientSocket = serverSocket.accept();
System.out.println("客戶端連線: " + clientSocket.getInetAddress().getHostAddress());
} catch (IOException e) {
System.err.println("Server 異常: " + e.getMessage());
}
}
public static void main(String[] args) {
new NetServer();
}
}
PC 端啟動 Server 後,PocketPC 透過 telnet 127.0.0.1 900 即可建立連線驗證。
引入 Thread 處理併發,每個連線獨立執行緒:
public class NetHelloServer {
public NetHelloServer() {
try {
ServerSocket serverSocket = new ServerSocket(900, 200);
while (true) {
Socket clientSocket = serverSocket.accept();
new Thread(new ClientHandler(clientSocket)).start();
}
} catch (IOException e) {
System.err.println("Server 異常: " + e.getMessage());
}
}
static class ClientHandler implements Runnable {
private Socket socket;
ClientHandler(Socket socket) { this.socket = socket; }
public void run() {
try (DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
out.writeUTF("請輸入您的姓名");
String name = in.readUTF();
out.writeUTF("收到: " + name + ",系統處理中...");
out.writeUTF(name + " 您好!");
System.out.println("Server 收到: " + name);
} catch (IOException e) {
System.err.println("處理異常: " + e.getMessage());
} finally {
try { socket.close(); } catch (IOException ignored) {}
}
}
}
public static void main(String[] args) { new NetHelloServer(); }
}
使用 AWT 建構簡易 GUI,包含姓名輸入、Server IP 設定、訊息顯示區、發送/離開按鈕:
public class HelloClient extends Frame {
private TextField tfName, tfServerIp;
private TextArea taMessages;
private Socket socket;
public HelloClient() {
// GUI 初始化佈局代碼...
btnSend.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
sendMessage();
}
});
}
private void sendMessage() {
String name = tfName.getText().trim();
String ip = tfServerIp.getText().trim();
if (name.isEmpty() || ip.isEmpty()) return;
try {
socket = new Socket(ip, 900);
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String msg = in.readUTF(); // "請輸入您的姓名"
taMessages.append("Server: " + msg + "\n");
out.writeUTF(name);
String reply1 = in.readUTF(); // "收到: xxx..."
taMessages.append("Server: " + reply1 + "\n");
String reply2 = in.readUTF(); // "xxx 您好!"
taMessages.append("Server: " + reply2 + "\n");
socket.close();
} catch (IOException ex) {
taMessages.append("錯誤: " + ex.getMessage() + "\n");
}
}
public static void main(String[] args) { new HelloClient(); }
}
架構分層:Client → Socket Server (業務邏輯) → JDBC → Database (HSQLDB)
class DBHandler extends Thread {
private Socket socket;
private static Connection conn;
DBHandler(Socket socket) { this.socket = socket; }
public void run() {
try (DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
out.writeUTF("請輸入查詢代碼");
String code = in.readUTF();
// 初始化資料庫 (僅首次)
if (!initialized) { initDatabase(); initialized = true; }
// 查詢 Place 表
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT Name FROM Place WHERE Code = " + code)) {
String name = rs.next() ? rs.getString(1) : "查無資料";
out.writeUTF("查詢結果: " + name);
}
} catch (Exception e) {
System.err.println("DB 處理異常: " + e.getMessage());
} finally {
try { socket.close(); } catch (IOException ignored) {}
}
}
}
public class HttpTest extends Frame {
private TextField tfUrl;
private TextArea taContent;
class FetchAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
URL url = new URL(tfUrl.getText());
try (BufferedReader br = new BufferedReader(
new InputStreamReader(url.openStream()))) {
String line;
while ((line = br.readLine()) != null) {
taContent.append(line + "\n");
}
}
} catch (Exception ex) {
taContent.append("錯誤: " + ex.getMessage());
}
}
}
}
注意:原始 HTTP 回應為 HTML 原始碼,需自行解析渲染(JS、CSS、圖片等資源需額外下載處理),這正是瀏覽器引擎的核心複雜度所在。
// 遠程介面
public interface CustWork extends Remote {
String getSrvMsg() throws RemoteException;
}
// 服務實作
public class CustWorkImpl extends UnicastRemoteObject implements CustWork {
public CustWorkImpl() throws RemoteException { super(); }
public String getSrvMsg() throws RemoteException {
String thread = Thread.currentThread().getName();
String time = Calendar.getInstance().getTime().toString();
System.out.println(thread + " : Client connected at " + time);
return thread + " : Message from Server at " + time;
}
}
public class RMIServerBootstrap {
public static void main(String[] args) {
try {
// 內建註冊中心 (埠口 1099)
LocateRegistry.createRegistry(1099);
CustWorkImpl service = new CustWorkImpl();
Naming.rebind("myServer", service);
System.out.println("RMI 服務已綁定: myServer");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class RMIClient {
public static void main(String[] args) {
try {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
CustWork service = (CustWork) Naming.lookup(
"rmi://192.168.0.1:1099/myServer");
System.out.println("Server 回應: " + service.getSrvMsg());
} catch (Exception e) {
e.printStackTrace();
}
}
}
| 項目 | J2SE 標準版 | PersonalJava / J2ME (PocketPC) |
|---|---|---|
| 編譯工具 | javac | jdk1.1.8\bin\javac (需相容舊版) |
| Stub/Skeleton 生成 | rmic | rmic -v1.1 (相容 1.1 協議) |
| 執行命令 | java | pjava (PersonalJava VM) |
| 安全策略 | java.policy | 需手動配置 C:\jdk1.3.1\jre\lib\security\java.policy |
| 部署檔案 | .class / .jar | 需包含 *_Stub.class 部署至裝置 |
# Server 端 (PC)
javac -classpath %pjeeclasspath%;hsql.jar netDBServer.java
pjava -classpath %pjeeclasspath%;hsql.jar netDBServer
# Client 端 (PocketPC)
javac -classpath %pjeeclasspath% Client.java
pjava -classpath %pjeeclasspath% Client
# 再複製 .class 至 PocketPC 執行
從基礎 Socket 到 RMI 分布式架構,Windows CE / PocketPC 平台上的 Java 網絡編程展現了「Write Once, Run Anywhere」的跨平台威力。雖然嵌入式 JVM 版本較舊(PersonalJava 基於 JDK 1.1.x),但核心網絡 API 保持高度相容,配合無線網卡、藍牙、行動通訊模組,即可構建實用的行動企業應用系統。