J2ME应用程序已经
我在应用开发过程中,经常用到J2ME的网络应用,但限于J2ME无线设备的能力,我们不得不在可用性和性能之间作出选择,因此,我做了以下的试验,并由此总结出一点结论,以方便后来者不必再走弯路。
我的应用主要功能是测试J2ME设备的网络连接性能,因此,其他方面的测试概不涉及。
我们知道,J2ME的通用连接框架为我们提供了http/socket/数据报/本地文件/线外等连接方式,但由于具体设备实现不同而导致程序开发方面的不便。举例来说,J2ME 的 MIDP 1.0版本中没有规定socket是必须的,但到了MIDP 2.0 socket才成为必须实现的协议。因此,现阶段大多数流行的设备都没有socket连接,这给我们编程带来了不利因素。在我们的测试程序中,SOCKET测试采用了StreamConnection类来建立连接,而走的是socket协议。分析一下程序即可知。
本文涉及了多种协议情况下的数据上传与下载,中文上传下载处理及网络传输计时、数据加密解密等方面的内容。为了做到通用,我在该程序的实现中没有用到特定设备的类。
本文给出的测试数据中第一个是建立连接所使用的时间,其余9项是连接建立后的数据传送时间。最后一项是前面9项数据的平均值。
测试结果数据比较:
机型,所用时间(秒),连接次数
SUN WTK 模拟器
HTTP 1.3910.1880.6250.1410.1410.3910.3130.2040.3750.4840.318
SOCK 0.5000.5310.1570.5310.3600.1720.3130.6410.4370.2660.378
Nokia6610
HTTP4.2581.6821.6121.3732.6811.8201.2641.5121.9191.8081.741
SOCK 未通过
Nokia 7650
HTTP 7.8122.7902.6412.5002.6303.9222.4382.6722.2192.594 2.712
SOCK 1.7191.3121.6093.3593.3601.3751.7813.3131.2501.329 2.076
Nokia 6600
HTTP 3.9371.9842.1721.6411.5001.5312.1251.9061.8432.1561.873
SOCK 3.1881.2811.4061.2661.8331.6881.7191.6881.6251.7031.579
索爱P802
HTTP 7.4841.4841.5001.8591.4851.5001.9381.7811.9381.7011.687
SOCK 1.3601.3281.2811.6251.4061.5921.1401.2811.3121.2971.362
从以上数据分析,我认为:
1、每一款机器每一种连接方式在同一时刻的网络连接速度波动都较大,即每一次连接都可能有导致网络连接滞后的不确定因素;
2、无论哪一种连接方式,无线设备的网络连接速度比PC连接要慢;
3、当前网络连接的时间超过了游戏者可接受的延迟,不适合做实时或即时性操作;
4、随着中国移动EDGE的上线,或者联通公司的CDMA1X普及,实时性手机应用将会得到发展,但仍需要进一步测试;
5、在无线应用网络连接术语中有呼叫建立延迟(Call Setup latency)和通话信号传输延迟(Intra-call latency)两种,从以上数据可以看出,第一种延迟要比后一种延迟要明显一些,即第一次连接时用户需要等待更多的时间;
以下是本文的代码片断:
public class Game extends MIDlet implements CommandListener {
private Display display;
private Form fmHTTP;
private Form fmHTTP2;
private Form fmStream;
private Form fmSocket;
private Command cmdTest = new Command("测试", Command.BACK, 0);
private Command cmdStream = new Command("STREAM", Command.ITEM, 1);
private Command cmdSocket = new Command("SOCKET", Command.ITEM, 2);
private Command cmdHTTP = new Command("HTTP", Command.ITEM, 3);
private TestThread testThread;
public Game() {
display = Display.getDisplay(this);
fmHTTP = new Form("1.HTTP测试");
fmHTTP.addCommand(cmdStream);
fmHTTP.addCommand(cmdSocket);
fmHTTP.addCommand(cmdHTTP2);
fmHTTP.addCommand(cmdExit);
fmHTTP.setCommandListener(this);
fmHTTP.append("HTTP协议网络测试工具用于检测手机是否具备HTTP网络连接能力。第一行数据是由服务器产生的,经过UTF编码和DES加密传输到手机上的。\n");
fmStream = new Form("3.STREAM测试");
fmStream.addCommand(cmdHTTP);
fmStream.addCommand(cmdHTTP2);
fmStream.addCommand(cmdSocket);
fmStream.setCommandListener(this);
fmStream.append("STREAM网络连接是走的socket端口,对应的服务器端口是10000。\n");
testThread = new TestThread(getAppProperty("Server").toLowerCase().trim());
}
class TestThread implements Runnable {
private String server;
private String message;
private Form curForm;
private int responseCode;
private InputStream is2;
private HttpConnection conHttp;
private String keyOptimize;
private HttpConnection conOptimize;
public TestThread(String server) {
this.server = server;
}
public void start(Form curForm) {
this.curForm = curForm;
Thread t = new Thread(this);
t.start();
}
public void run() {
message = "";
long start,timeused;
int formid = Integer.parseInt(curForm.getTitle().substring(0,1));
start = System.currentTimeMillis(); //网络用时测试起点
if (formid==1) {//1.HTTP测试
try {
String key = genPassWord(); //产生8位的随机字符串密码,用于返回给服务器进行DES加密
conHttp = (HttpConnection) Connector.open("http://" + server + ":8080/ns/hellodes?r=" + key);
responseCode = conHttp.getResponseCode();
if (responseCode==HttpConnection.HTTP_OK){
InputStream is = conHttp.openInputStream();
int len = (int) conHttp.getLength();
byte[] bytestr = new byte[len];
is.read(bytestr); //直接从输入流中读取字节,
cipher = new DesCipher(key.getBytes());
for (int i = 0; i < bytestr.length / 8; i++) {
cipher.decrypt(bytestr, i * 8, bytestr, i * 8); //解密;
}
message = gbDecode(new String(bytestr)); //解码
is.close();
is = null;
}else{
message = "服务器无法连接!" + responseCode;
}
} catch (Exception e) {
message = e.getMessage();
}
} else if (formid==3) {//3.STREAM测试
try {
conStream = (StreamConnection) Connector.open("socket://"+ server + ":10000", Connector.READ_WRITE);
InputStream is = conStream.openInputStream();
byte[] outs = new byte[20];
int len = 0, ch;
while ((ch = is.read()) != -1) {
outs[len] = (byte) ch;
len++;
}
byte[] bytestr = new byte[len];
System.arraycopy(outs, 0, bytestr, 0, len);
message = gbDecode(new String(bytestr));
is.close();
is = null;
} catch (Exception e) {
message = e.getMessage();
}
} else if (formid==4) {//SOCKET测试
/*
try {
sck = (SocketConnection)Connector.open("socket://"+server+":10009",Connector.READ_WRITE);
sck.setSocketOption(SocketConnection.LING