在 J2ME 移動應用開發中,網絡通訊是核心功能之一。本文將通過實例代碼,詳細剖析 J2ME 中最常用的兩種網絡連接方式——HTTP 協議與 Socket 長連接,幫助開發者快速掌握移動端網絡編程精髓。
HttpConnection 採用標準 HTTP 協議,適合簡單的數據交互場景(如用戶登錄驗證、數據查詢)。以下是完整的 GET 請求實現:
import javax.microedition.io.*;
public String requestGET(String URLString, String URL) throws IOException {
HttpConnection hpc = null;
DataInputStream dis = null;
String content = "";
try {
// 建立連接
hpc = (HttpConnection) Connector.open(URLString + URL);
hpc.setRequestMethod(HttpConnection.GET);
dis = new DataInputStream(hpc.openInputStream());
// 讀取響應數據
int character;
boolean newline = false;
while ((character = dis.read()) != -1) {
if ((char) character == '\r') {
newline = true;
continue;
} else {
if ((char) character == '\n' && newline) {
content += " ";
newline = false;
} else if (newline) {
content += "" + (char) character;
newline = false;
} else {
content += (char) character;
newline = false;
}
}
}
} catch (IOException e) {
System.out.print("ERROR: " + e);
} finally {
// 釋放資源
if (hpc != null) { hpc.close(); hpc = null; }
if (dis != null) dis.close();
}
// 中文字符集轉換(關鍵步驟)
content = unicodeToGb2312(content).trim();
return content;
}
// 編碼轉換工具方法
public static String unicodeToGb2312(String s) {
if (s == null || s.equals("")) return s;
try {
return new String(s.getBytes("ISO8859_1"), "GB2312");
} catch (Exception e) {
return s;
}
}
Connector.open() 創建 HttpConnection 實例適合短連接、請求響應模式的業務:用戶認證、表單提交、數據查詢、配置下載等。服務端只需部署普通 JSP/Servlet 即可,無需額外協議支持。
private StreamConnection conServer;
private String strServerAddr;
private boolean bConnected = false;
public boolean socketConn(String serverAddr) throws IOException {
strServerAddr = serverAddr; // 格式:socket://192.168.0.1:6666
try {
conServer = (StreamConnection) Connector.open(strServerAddr);
bConnected = true;
System.out.println("Socket 連接成功!");
return true;
} catch (Exception e) {
System.out.println("連接失敗: " + e);
bConnected = false;
return false;
}
}
// 服務端啟動監聽
ServerSocketConnection serverSocket = (ServerSocketConnection) Connector.open("socket://:6666");
while (true) {
// 阻塞等待客戶端連接
SocketConnection clientSocket = (SocketConnection) serverSocket.acceptAndOpen();
// 為每個客戶端創建獨立處理線程
new Thread(new ClientHandler(clientSocket)).start();
}
// 發送數據
protected boolean sendData(byte[] data) {
if (!bConnected) return false;
OutputStream os = null;
try {
os = conServer.openOutputStream();
os.write(data);
os.flush(); // 強制發送緩衝區數據
return true;
} catch (Exception e) {
disconnect(); // 異常時斷開重連
return false;
} finally {
if (os != null) try { os.close(); } catch (Exception ignored) {}
}
}
// 接收數據(類似發送,將 OutputStream 改為 InputStream)
作者實踐發現:中國移動 GPRS 網絡分配的是虛擬 IP,且隨基站切換而變化。這導致服務端無法通過固定 IP 向客戶端主動推送數據(廣播失效)。
解決方案:採用客戶端主動輪詢/心跳機制,由客戶端定時發送請求獲取服務端數據,而非依賴服務端主動連接。
| 維度 | HttpConnection | SocketConnection |
|---|---|---|
| 協議類型 | HTTP/1.1 (應用層) | TCP (傳輸層) |
| 連接模式 | 短連接,請求響應 | 長連接,持久會話 |
| 服務端部署 | 普通 Web 容器 (Tomcat/JSP) | 獨立 Socket 服務程序 |
| 穿透防火牆 | 極佳 (80/443 端口常開放) | 較差 (需開放特定端口) |
| 實時性 | 低 (需輪詢) | 高 (服務端可主動推送) |
| 適用業務 | CRUD 操作、認證、配置 | 即時通訊、遊戲、股票行情 |
| 移動網適應性 | 良好 (無狀態) | 需處理斷線重連、IP 變更 |
J2ME 網絡編程的核心在於根據業務特性選擇協議:簡單查詢用 HTTP,實時互動用 Socket。移動網絡環境的不確定性(弱網、斷網、IP 漂移)要求代碼具備健壯的異常處理與重連能力。掌握這兩種技術,即可應對 90% 以上的 J2ME 網絡開發場景。