MIDP 2.0 引入了 javax.microedition.io 套件,提供 SocketConnection、ServerSocketConnection 與 UDPDatagramConnection 三大介面,支援 TCP/IP 與 UDP 低階網路通訊。本文重點介紹如何在 MIDlet 中使用 SocketConnection 與 TCP 伺服器進行資料交換。
透過 Connector.open() 方法即可建立連線,URL 格式為 socket://<host>:<port>:
SocketConnection client = (SocketConnection) Connector.open(
"socket://" + hostname + ":" + port
);
// 設定 Socket 選項:關閉 Nagle 演算法、啟用保持連線
client.setSocketOption(SocketConnection.DELAY, 0);
client.setSocketOption(SocketConnection.KEEPALIVE, 0);
InputStream is = client.openInputStream();
OutputStream os = client.openOutputStream();
// 發送資料
os.write("Hello Server".getBytes());
// 接收回應
int ch;
while ((ch = is.read()) != -1) {
// 處理回應資料
}
is.close();
os.close();
client.close();
網路操作屬於阻塞性作業,必須在獨立執行緒執行,避免凍結使用者介面。採用 wait()/notify() 機制讓工作執行緒待命,僅在使用者觸發動作時喚醒:
class CommandThread extends Thread {
private MIDlet parent;
private boolean commandAvailable = false;
public CommandThread(MIDlet parent) {
this.parent = parent;
}
public synchronized void run() {
while (!exit) {
synchronized (parent) {
while (!commandAvailable) {
try { parent.wait(); }
catch (InterruptedException e) {}
}
}
commandAvailable = false;
// 執行網路操作...
}
}
public synchronized void trigger() {
commandAvailable = true;
notify();
}
}
public class DayTimeServer {
public static void main(String[] args) {
int port = 13; // 標準 Daytime 協定埠
if (args.length == 1) port = Integer.parseInt(args[0]);
try (ServerSocket server = new ServerSocket(port)) {
while (true) {
try (Socket sock = server.accept();
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(sock.getOutputStream()))) {
String time = new Date().toString();
out.write(time.getBytes());
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class DayTimeClient extends MIDlet implements CommandListener {
private Display display;
private Form resultForm;
private StringItem timeItem;
private CommandThread netThread;
private String serverUrl;
protected void startApp() {
String host = getAppProperty("HOST");
String port = getAppProperty("DAYTIME_PORT");
serverUrl = "socket://" + host + ":" + port;
display = Display.getDisplay(this);
resultForm = new Form("Time");
timeItem = new StringItem(null, null);
resultForm.append(timeItem);
netThread = new CommandThread(this);
netThread.start();
display.setCurrent(resultForm);
}
// CommandListener 實作與網路執行緒互動...
}
MIDlet-Name: DayTimeClient
MIDlet-Version: 1.0
MIDlet-Vendor: Example
MIDlet-1: DayTimeClient,,DayTimeClient
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
HOST: 127.0.0.1
DAYTIME_PORT: 13
InputStream、OutputStream、Connection 釋放資源SocketConnection(屬選配功能)掌握 SocketConnection 後,您可開發即時通訊、遊戲對戰、資料同步等需要低延遲、雙向通訊的 J2ME 應用。建議搭配 WTK 模擬器與真機進行充分測試。