我这天,开发网络连接程序,遇到n多问题,都得以解决。
总结一下。
首先是环境。
我用的开发SDK和模拟器都是Sun的,J2ME Wireless Toolkit 2.2
现在UltraEdit下面写一个网络程序。注意一定要在网络连接动作时,另外启动一下线程,否则模拟器运行会有错误。
很不好的代码:不要使用!!!!!!!!!!
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class MainMidlet extends MIDlet
implements CommandListener


{
private Display display;

public MainMidlet()
{
super();
display = Display.getDisplay(this);
}
private Form f;
private TextField server;
private TextField port;
private TextBox showBox;

protected void startApp() throws MIDletStateChangeException
{
f = new Form("Test Network");
server = new TextField("服务器","www.google.com",20,TextField.ANY);
port = new TextField("端口","80",4,TextField.NUMERIC);
showBox = new TextBox("连接数据", "Init",1024,TextField.ANY);
showBox.addCommand(new Command("返回",Command.BACK,1));
showBox.setCommandListener(this);
f.append(server);
f.append(port);
f.addCommand(new Command("Socket连接",Command.SCREEN,1));
f.addCommand(new Command("Http连接",Command.SCREEN,1));
f.setCommandListener(this);
display.setCurrent(f);
}


protected void pauseApp()
{
// TODO Auto-generated method stub

}


protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
// TODO Auto-generated method stub

}


public void commandAction(Command arg0, Displayable arg1)
{
if(arg0.getLabel().equals("Socket连接"))

{
socketconnect();
}
else if(arg0.getLabel().equals("Http连接"))

{
httpconnect();
}
else if(arg0.getLabel().equals("返回"))

{
display.setCurrent(f);
}
}
private void socketconnect()

{
StreamConnection socket = null;
InputStream is = null;
OutputStream os = null;

try
{
String name = "http://" + server.getString() + ":" + port.getString();
socket = (StreamConnection)Connector.open(name,Connector.READ_WRITE);
String request = "GET / HTTP/1.0\n\n";
os = socket.openOutputStream();
os.write(request.getBytes());
is = socket.openInputStream();
final int MAX_LENGTH = 128;
byte[] buf = new byte[MAX_LENGTH];
int total = 0;

while(total < MAX_LENGTH)
{
int count = is.read(buf,total, MAX_LENGTH - total);
if(count < 0)

{
break;
}
total += count;
}
String toshow = new String(buf,0,buf.length);
showBox.setString(toshow);
display.setCurrent(showBox);
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,f);

}finally
{
if(is != null)

{

try
{
is.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,f);
}
is = null;
}
if(os != null)

{

try
{
os.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,f);
}
os = null;
}
if(socket != null)

{

try
{
socket.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,f);
}
socket = null;
}
}
}
private void httpconnect()

{
HttpConnection conn = null;
InputStream is = null;
OutputStream os = null;

try
{
String url = "wap.winwap.com";
conn = (HttpConnection)Connector.open("http://10.0.0.172/" + "home.wml");
conn.setRequestProperty("X-Online-Host",url);
conn.setRequestMethod(HttpConnection.GET);
if(conn.getResponseCode() == HttpConnection.HTTP_OK)

{
is = conn.openInputStream();
final int MAX_LENTH = 128;
byte[] buf = new byte[MAX_LENTH];
int total = 0;
while(total < MAX_LENTH)

{
int count = is.read(buf,total,MAX_LENTH - total);
if(count < 0)
break;
total += count;
}
is.close();
String reply = new String(buf,0,total);
showBox.setString(reply);
display.setCurrent(showBox);

}else
{
showBox.insert(String.valueOf(conn.getResponseCode()),showBox.getCaretPosition());
showBox.insert(String.valueOf(HttpConnection.HTTP_OK),showBox.getCaretPosition());
display.setCurrent(showBox);
}
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,showBox);

}finally
{
if(is != null)

{

try
{
is.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,showBox);
}
is = null;
}
if(os != null)

{

try
{
os.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,showBox);
}
os = null;
}
if(conn != null)

{

try
{
conn.close();
}catch(Exception ex)

{
Alert al = new Alert("未定义异常", ex.getMessage(), null, AlertType.ALARM);
al.setTimeout(Alert.FOREVER);
display.setCurrent(al,showBox);
}
conn = null;
}
}
}

}

这段代码,在模拟器上运行很有问题!

这以后,再按钮就没有反应了,而且,会有警告warning
警告: 若要避免潜在的死锁,应该在 commandAction() 处理程序之外的其他线程中执行
可能会阻塞的
操作(如网络连接)。
模拟器再不能正常链接了。无法配置。
===============================================
改代码如下:
import javax.microedition.io.*;
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class QueryForm extends TextBox implements CommandListener


{
MIDlet midlet ;
public QueryForm(MIDlet m)

{
super("请输入网址","http://wap.winwap.com",40,TextField.ANY) ;
midlet = m ;
addCommand(new Command("离开",Command.SCREEN,1)) ;
addCommand(new Command("查询",Command.SCREEN,1)) ;
setCommandListener(this) ;
}
public void commandAction(Command c,Displayable s)

{
String cmd = c.getLabel() ;
if(cmd.equals("离开"))

{
midlet.notifyDestroyed() ;
}else if(cmd.equals("查询"))

{
String url = getString() ; //连接网址
WorkThread wt = new WorkThread(url,Display.getDisplay(midlet)) ;
wt.start() ;
}
}
}
import javax.microedition.io.*;
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyHttpClient extends MIDlet


{
Display display ;
public MyHttpClient()

{
display = Display.getDisplay(this) ;
}
public void startApp()

{
display.setCurrent(new QueryForm(this));
}
public void pauseApp()

{
}
public void destroyApp(boolean con)

{
}
}
import javax.microedition.io.*;
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class WorkThread extends Thread


{
String url ;
Display display ;
public WorkThread(String url,Display d)

{
this.url = url ;
display = d ;
System.out.println("准备连接:"+this.url) ;
}
public void run()

{
HttpConnection conn = null;
InputStream is = null;
InputStreamReader isr = null ;
StringBuffer line = new StringBuffer("");

try
{
conn = (HttpConnection)Connector.open(url);
System.out.println("内容长度:" + conn.getLength()) ;
is = conn.openInputStream();
isr = new InputStreamReader(is) ;
int ic ;
while( (ic = isr.read()) != -1 )

{
line.append((char)ic) ;
}
}catch (Exception ioe)

{
System.out.println(ioe);
}finally

{
try

{
if(conn!=null)
conn.close();

}catch(Exception e)
{}
}
Alert al = new Alert("查询结果",line.toString(),null,AlertType.CONFIRMATION);
al.setTimeout(Alert.FOREVER) ;
display.setCurrent(al) ;
}
}
可以了,在运行代码,就会看到模拟同样出现提示,但是确认后,模拟器会走本地的网络,链接站点。




OK,成功在模拟器上访问了。
注意,这仅仅是模拟器,部署到手机上,要对程序稍加改动,才能用。
在中国移动提供的网络连接中,分为CMNET和CMWAP两种,其中CMNET可以无限制的访问互联网络,资费比较贵。CMWAP类似一个HTTP的代码,只能访问支持HTTP的应用,但是资费便宜,稳定性比较差。
在实际的J2ME网络编程中,一般需要提供以CMWAP代理的方式连接网络,在J2ME中,连接的代码和直接连接有所不同,代码如下:
HttpConnection http = (HttpConnection)Connector.open(("http://10.0.0.172/"+url);
http.setRequestProperty("X-Online-Host",ServerName);
例如你需要访问的地址为:http://www.test.com/login/loginServlet则上面的代码就为:
HttpConnection http = (HttpConnection)Connector.open(("http://10.0.0.172/" + "login/loginServlet");
http.setRequestProperty("X-Online-Host","www.test.com");
在实际使用过程中,只需要使用实际需要访问的地址的域名或者IP来代替ServerName,例如示例中的“www.test.com”,使用后续的地址类代替代码中的url,例如示例中的“login/loginServlet”,就可以实际的使用CMWAP代理来进行连接了。
呜呼,休息一下,在达内学习完C++,最强大的多范型语言,学习J2ME只需要一周就足够了。好比是九阳神功在体内,无所不能。阿,哈哈哈。Java乃是乾坤大挪移。
posted on 2006-02-05 13:28
北国狼人的BloG 阅读(4977)
评论(0) 编辑 收藏 所属分类:
达内学习总结