在 J2ME 開發領域,網絡通信是構建移動互聯應用的基石。本文將系統性剖析 J2ME 中兩種核心網絡編程方式 —— HttpConnection(基於 HTTP 協議)與 SocketConnection(基於 TCP Socket),並通過實戰代碼示例,幫助開發者掌握從客戶端請求到服務端響應的完整開發流程。
HttpConnection 封裝了 HTTP/1.1 協議,適合與 Web 服務器(如 Tomcat、IIS)進行標準請求響應交互。其優勢在於無需自行處理協議細節,開發效率極高。
import javax.microedition.io.*;
import java.io.*;
public String requestGET(String urlString, String params) throws IOException {
HttpConnection hpc = null;
DataInputStream dis = null;
String content = "";
boolean newline = false;
try {
// 建立連接
hpc = (HttpConnection) Connector.open(urlString + params);
hpc.setRequestMethod(HttpConnection.GET);
dis = new DataInputStream(hpc.openInputStream());
// 讀取響應數據
int character;
while ((character = dis.read()) != -1) {
if ((char) character == '\\') {
newline = true;
continue;
} else {
if ((char) character == 'n' && newline) {
content += "\n";
newline = false;
} else if (newline) {
content += "\\" + (char) character;
newline = false;
} else {
content += (char) character;
newline = false;
}
}
}
} catch (IOException e) {
System.out.println("ERROR: " + e);
} finally {
if (hpc != null) { hpc.close(); hpc = null; }
if (dis != null) dis.close();
}
// 處理中文編碼轉換(ISO-8859-1 → GB2312)
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(url) 並強制轉型為 HttpConnectionsetRequestMethod() 設置openInputStream() 獲取輸入流finally 塊中必須關閉連接與流,防止內存洩漏SocketConnection 提供 TCP 層面的全雙工通信,適合即時通訊、遊戲對戰、推送服務等場景。雖然開發複雜度較高,但能實現服務端主動推送數據。
private StreamConnection conServer;
private String strServerAddr;
private boolean bConnected;
public boolean socketConn(String addr) throws IOException {
conServer = null;
strServerAddr = addr; // 格式:socket://192.168.0.1:6666
bConnected = false;
try {
conServer = (StreamConnection) Connector.open(strServerAddr);
} catch (Exception e) {
System.out.println("Connect server error");
return false;
}
bConnected = true;
System.out.println("connect ok!");
return true;
}
// 服務端偽代碼邏輯
ServerSocketConnection server = (ServerSocketConnection) Connector.open("socket://:6666");
while (true) {
SocketConnection client = (SocketConnection) server.acceptAndOpen();
// 為每個客戶端創建獨立線程處理 I/O
new Thread(() -> handleClient(client)).start();
}
// 發送數據
protected boolean sendData(byte[] data) {
if (!bConnected) return false;
OutputStream os = null;
try {
os = conServer.openOutputStream();
os.write(data);
os.flush();
os.close();
return true;
} catch (Exception e) {
bConnected = false;
disconnect();
return false;
}
}
// 接收數據(類似發送,將 OutputStream 改為 InputStream)
InputStream is = conServer.openInputStream();
// 使用 is.read() 循環讀取...
在 GPRS/3G 網絡中,手機獲取的是運營商分配的虛擬 IP,而非公網真實 IP。當用戶移動基站切換時,虛擬 IP 可能發生變化,導致服務端無法通過原 IP 向客戶端發起連接。因此長連接心跳機制與客戶端主動上報成為必然選擇。
| 維度 | HttpConnection | SocketConnection |
|---|---|---|
| 協議層級 | 應用層 (HTTP) | 傳輸層 (TCP) |
| 連接模式 | 短連接/請求響應 | 長連接/全雙工 |
| 穿透防火牆 | 極佳 (80/443 端口) | 較差 (需開放特定端口) |
| 服務端推送 | 需輪詢/Comet/WebSocket | 原生支持 |
| 開發複雜度 | 低 | 高 (需處理粘包、心跳、重連) |
| 適用場景 | 數據查詢、表單提交、文件下載 | 即時通訊、多人遊戲、股票行情推送 |
Thread 或 Runnable掌握這兩種網絡編程範式,並根據業務場景靈活選型,是成為優秀 J2ME 架構師的關鍵能力之一。