J2ME 基於 GCF (Generic Connection Framework) 提供統一網絡接口,支持 HTTP/HTTPS、Socket、Datagram、Comm 等協議。本文通過 Tomcat 搭建 Web 服務端,演示文本/圖片/音頻下載、用戶登錄、網絡猜價格遊戲完整實現,覆蓋客戶端與服務端雙向代碼。
C:\j2sdk1.4.2_05)C:\Tomcat 5.0),管理員 admin/123,端口 8080Context Path=/515game → D:/mygameWebhttps://127.0.0.1:8080/515game/test.html
String url = "https://127.0.0.1:8080/515game/myweb.html";
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
StringBuffer sb = new StringBuffer();
int ch;
while ((ch = is.read()) != -1) sb.append((char) ch);
is.close(); sc.close();
// 中文解碼: ISO-8859-1 → UTF-8
String text = new String(sb.toString().getBytes("ISO-8859-1"), "UTF-8");
String url = "https://127.0.0.1:8080/515game/bg.png";
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
Image img = Image.createImage(is); // MIDP 2.0 直接支持流創建圖片
is.close(); sc.close();
form.append(img);
String url = "https://127.0.0.1:8080/515game/bgm.wav";
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
Player player = Manager.createPlayer(is, "audio/x-wav");
player.start();
sc.close(); // 注意: player 異步播放,流關閉不影響播放
<%
String name = request.getParameter("username");
String pass = request.getParameter("passWord");
if ("ldh".equals(name)) {
if ("zhm".equals(pass)) out.print("welcome ");
else out.print("pass Word error");
} else {
out.print("user name error");
}
%>
public class LoginMidlet extends MIDlet implements CommandListener, Runnable {
Form form; TextField user, pass; Command ok;
public LoginMidlet() {
form = new Form("用戶登錄");
user = new TextField("用戶名", "", 10, TextField.ANY);
pass = new TextField("密碼", "", 8, TextField.PASSWORD);
form.append(user); form.append(pass);
ok = new Command("登錄", Command.OK, 1);
form.addCommand(ok); form.setCommandListener(this);
}
public void commandAction(Command c, Displayable d) {
if (c == ok) new Thread(this).start(); // 網絡操作必須異步
}
public void run() {
try {
String url = "https://127.0.0.1:8080/515game/checkuser.jsp?username="
+ user.getString() + "&passWord=" + pass.getString();
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
StringBuffer sb = new StringBuffer();
int ch;
while ((ch = is.read()) != -1) sb.append((char) ch);
is.close(); sc.close();
Form result = new Form("登錄結果");
result.append(sb.toString());
Display.getDisplay(this).setCurrent(result);
} catch (Exception e) {
e.printStackTrace();
}
}
// startApp/pauseApp/destroyApp 省略
}
<%
String param = request.getParameter("jg");
int serverPrice = (int)(Math.random() * 10); // 0-9 隨機價格
int userPrice = Integer.parseInt(param);
if (userPrice > serverPrice) out.println("sorry da le"); // 大了
else if (userPrice < serverPrice) out.println("sorry xiao le"); // 小了
else out.println("right"); // 猜中
%>
public class GuessGame extends MIDlet implements CommandListener, Runnable {
Form mainForm, resultForm; TextField input; Command guess, back; Display disp;
public GuessGame() {
mainForm = new Form("商品競猜");
input = new TextField("輸入價格 1-9", "", 1, TextField.NUMERIC);
guess = new Command("猜", Command.OK, 1);
mainForm.append(input); mainForm.addCommand(guess); mainForm.setCommandListener(this);
resultForm = new Form("結果");
back = new Command("返回", Command.BACK, 1);
resultForm.addCommand(back); resultForm.setCommandListener(this);
disp = Display.getDisplay(this);
}
public void startApp() { disp.setCurrent(mainForm); }
public void commandAction(Command c, Displayable d) {
if (c == guess) new Thread(this).start();
else if (c == back) disp.setCurrent(mainForm);
}
public void run() {
try {
String url = "https://127.0.0.1:8080/515game/Guess.jsp?jg=" + input.getString();
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
StringBuffer sb = new StringBuffer();
int ch;
while ((ch = is.read()) != -1) sb.append((char) ch);
is.close(); sc.close();
// 清空舊結果並顯示新結果
for (int i = 0; i < resultForm.size(); i++) resultForm.delete(i);
resultForm.append(sb.toString());
disp.setCurrent(resultForm);
} catch (Exception e) {
e.printStackTrace();
}
}
}
| 維度 | HTTP 短連接 (當前) | Socket 長連接 (進階) |
|---|---|---|
| 連接建立 | 每請求一次 TCP 三次握手 | 啟動時一次,心跳保活 |
| 服務端推送 | 不支持 (需輪詢/Comet) | 原生支持 |
| 延遲 | 高 (RTT + 服務端處理) | 極低 (單向推送) |
| 並發壓力 | 高 (大量 TIME_WAIT) | 低 (連接復用) |
| 穿透防火牆 | 優 (80/443) | 需協調開放端口 |
| 適用遊戲類型 | 回合制/卡牌/社交 | 即時對戰/竞速/MMORPG |