class Task {
public Task () {
this.url = null;
this.tag = null;
this.hrefSpell = null;
this.query = null;
this.doubleQuote = true;
}
public Task(String anUrl, String aTag, String aHrefSpell, String aQuery, boolean aDoubleQuote) {
this.url = anUrl;
this.tag = aTag;
this.hrefSpell = aHrefSpell;
this.query = aQuery;
this.doubleQuote = aDoubleQuote;
}
String url;
String tag;
String hrefSpell;
String query;
boolean doubleQuote;
}
import java.io.UnsupportedEncodingException;
//
// URL.java
// maol.osx
//
// Created by lujnan on 07-11-1.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
/** <pre>
* Description: This is the URL class represents an Uniform Resource Locator.
* URL is a compact string of characters used to represent a resource available
* on the Internet. It is also the global address of documents and other
* resources on the World Wide Web.
*
* The first part of the address is scheme, it is a protocol identifier and
* indicates what protocol to use, the second part is host which specifies
* the IP address or the domain name, the third part is port of the web server,
* the forth part is path which specifies where the resource is located.
* The protocol identifier and the resource name are separated by a colon and two
* forward slashes.
*
* Copyright: Zhejiang SU square technology co.,Ltd. </pre>
*
* @author nanger@su-fun.com
* @version 1.0 07-07-02
*/
public class URL {
/** the characters defined in RFC1738 could be used in URL scheme*/
public static final String stuffFromRFC1738 = "<>\"#%{}|\\^~[]`";
/** the protocol identifier appointed by URL to indicate what protocol to use */
protected String schema;
/** the domain name of the host computer */
protected String hostName;
/** the port number of the host computer */
protected int port;
/** the path of the source in the host computer */
protected String path;
/** the part of the URL used to query which begin with '?' */
protected String query;
/** the fragment part of the URL which begin with '#' */
protected String fragment;
/** the name of user */
protected String userName;
/** the password to enter */
protected String password;
/** the value to indicate whether the URL is valid */
protected boolean isValid;
/**
* Construct a new URL through parsing the appointed characters.<br>
* Judge whether the URL is valid through using the isValid method of URL.
*
* @param encodedUrl String (character string type) the URL character need parsed
*/
public URL(String encodedUrl) {
port = -1;
if (encodedUrl != null) {
path = encodedUrl;
int pos = path.indexOf('#');
if (pos != -1) {
fragment = path.substring(pos+1);
path = path.substring(0, pos);
}
pos = path.indexOf('?');
if (pos != -1) {
query = path.substring(pos+1);
path = path.substring(0, pos);
}
pos = path.indexOf(':');
if (pos != -1) {
if (path.indexOf('/') < 0 && path.indexOf('@', pos) > pos) {
schema = path.substring(0, pos);
path = path.substring(pos+1);
}
else if (path.length() >= pos+2 && path.charAt(pos+1) == '/' && path.charAt(pos+2) == '/') {
schema = path.substring(0, pos);
path = path.substring(pos+1);
}
}
if (path.charAt(0) == '/' && path.charAt(1) == '/') {
path = path.substring(2);
}
pos = path.indexOf('/');
if (pos == -1) {
hostName = path.substring(0);
path = "/";
}
else {
hostName = path.substring(0, pos);
path = path.substring(pos);
}
pos = hostName.indexOf('@');
if (pos != -1) {
int div = hostName.indexOf(':');
if (div < pos) {
userName = hostName.substring(0, div);
password = hostName.substring(div+1, pos);
hostName = hostName.substring(pos+1);
}
}
else {
pos = hostName.indexOf(':');
if (pos != -1 && (pos != (hostName.length() - 1))) {
port = Integer.valueOf(hostName.substring(pos+1)).intValue();
hostName = hostName.substring(0, pos);
}
}
if (path == null || path.length() == 0) {
path = "/";
}
if (hostName == null) {
isValid = false;
}
else {
isValid = true;
}
}
else {
isValid = false;
}
}
/**
* Judge whether the character need to be encoded.<br>
* For the HTTP is the text protocol, the characters of URL which<br>
* writes into the HTTP will destroy the HTTP rule.<br>
* So some characters of the URL address should be encoded.
*
* @param ch the character need to judge
* @return <code>true</code> for not need encoded, or <code>false</code> for need
*/
public static boolean needEncode(byte ch) {
/* unsafe chars:
- anything <= 32;
- stuff from rfc1738("<>\"#%{}|\\^~[]`");
- '@' and ':'; needed for encoding URL username and password
- anything >= 127. */
if (ch <= 32)
return true;
if (ch >= 127)
return true;
if (ch == '@' || ch == ':' || ch == ';' || ch == '/' || ch == '?' || ch == '&' || ch == '=')
return true;
if (stuffFromRFC1738.indexOf(ch) >= 0)
return true;
return false;
}
/**
* Encode the character string.<br>
* For the HTTP is the text protocol, the characters of URL which<br>
* writes into the HTTP will destroy the HTTP rule.<br>
* So some characters of the URL address should be encoded.
*
* @param toEncode the URL characters need to be encoded
* @return return the characters which have been encoded
*/
public static String encodeString(String toEncode) {
if (toEncode == null || toEncode.length() == 0) {
return null;
}
byte bt[] = null;
try {
bt = toEncode.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e) {
bt = toEncode.getBytes();
}
int iSize = bt.length;
StringBuffer result = new StringBuffer();
for (int i = 0; i < iSize; ++i) {
byte ch = bt[i];
if (needEncode(ch)) {
char chars[] = new char[3];
chars[0] = '%';
int v = ((ch&0xf0)>>4);
if (v<10) {
chars[1] = (char)(v+'0');
} else {
chars[1] = (char)(v-10+'A');
}
v = (ch&0x0f);
if (v<10) {
chars[2] = (char)(v+'0');
} else {
chars[2] = (char)(v-10+'A');
}
result.append(chars);
} else {
char cc = (char)ch;
result.append(cc);
}
}
return result.toString();
}
/**
* Decode URL characters.<br>
* For the characters of URL which has been encoded to fit the HTTP protocol,<br>
* the decoding operation should be done to get the original characters.
*
* @param toDecode the URL characters need to decode
* @return the URL characters which have been decoded
*/
public static String decodeString(String toDecode) {
char result [] = toDecode.toCharArray();
int i, iSize = toDecode.length();
int count = 0;
for (count = 0, i = 0; i < iSize; ++i) {
char ch = toDecode.charAt(i);
if (ch != '%') {
result[count++] = ch;
}
else {
int k = ++i;
ch = toDecode.charAt(k);
while((Character.isDigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) && (k <= i+1)) {
++k;
ch = toDecode.charAt(k);
}
result[count++] = (char) Integer.valueOf("0x"+toDecode.substring(i, k)).intValue();
i = k-1;
}
}
return (new String(result, 0, count));
}
/**
* Get the scheme of URL.
*
* @return the scheme of URL, or <code>null</code> if the scheme isn't defined
*/
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
if (schema != null && schema.length() != 0)
this.schema = new String(schema);
else
this.schema = null;
}
/**
* Get the host domain name of URL.
*
* @return the host domain name of URL, or <code>null</code> if the host isn't defined
*/
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
if (hostName != null && hostName.length() != 0) {
this.hostName = encodeString(hostName);
}
else {
this.isValid = false;
hostName = null;
}
}
/**
* Get the path of this URL which have been encoded
*
* @return the path of this URL which have encoded, or <code>null</code> if the path isn't defined
*/
public String getPath() {
return path;
}
public void setPath(String path) {
if (path != null && path.length() != 0) {
String toEncode = null;
if (path.charAt(0) == '/') {
toEncode = path.substring(1);
}
else {
toEncode = new String(path);
}
toEncode = encodeString(toEncode);
this.path = "/" + toEncode;
}
else
this.path = null;
}
/**
*Get the port of this URL.
*
* @return the port of this URL, or <code>-1</code> if the port isn't defined
*/
public int getPort() {
if (port <= 0) {
if (schema != null) {
if (schema.equalsIgnoreCase("ftp"))
return 21;
else if (schema.equalsIgnoreCase("https"))
return 443;
}
return 80;
}
return port;
}
/**
* Get the fragment part of this URL which have been encoded. <br>
* The fragment is indicated by the sharp sign character "#" followed by more characters. <br>
* The fragment indicates that after the specified resource is retrieved, the <br>
* application is specifically interested in that part of the document that has the <br>
* tag after the "#" attached to it.
*
* @return the fragment part of this URL which have been recoded, <br>
* or <code>null</code> if the fragment isn't defined
*/
public String getFragment() {
return fragment;
}
/**
* Set the fragment part of this URL. <br>
* The fragment will be encoded.
* @param fragment
*/
public void setFragment(String fragment) {
if (fragment != null) {
String encoded = encodeString(fragment);
this.fragment = encoded;
}
else
this.fragment = null;
}
/**
* Get the query part of this URL which have been encoded.
*
* @return the query part of this URL which have been encoded,<br>
* or <code>null</code> if the query isn't defined
*/
public String getQuery() {
return query;
}
public void clearQuery() {
query = null;
}
/**
* Add a query item. <br>
* name and value will be encoded.
*
* @param name the name of query item, must not <code>null</code> or length() equals to zero.
* @param value
* @return <code>true</code> for success, or <code>false</code> for failure.
*/
public boolean addQuery(String name, String value) {
if (name == null || name.length() == 0)
return false;
if (this.query == null) {
this.query = "";
}
if (this.query.length() != 0) {
this.query += "&";
}
this.query += encodeString(name);
this.query += "=";
String encoded = encodeString(value);
if (encoded != null) {
this.query += encoded;
}
return true;
}
/**
* Get the user's message part of this URL which have been encoded.
*
* @return the user's message part of this URL which have been encoded,<br>
* or <code>null</code> if the user's message isn't defined
*/
public String getUserName() {
return userName;
}
/**
* Set the username of URL. <br>
* userName will be encoded.
*
* @param userName the username of URL.
*/
public void setUserName(String userName) {
if (userName != null && userName.length() != 0)
this.userName = encodeString(userName);
else
this.userName = null;
}
/**
* Get the password part of this URL which have been encoded.
*
* @return the password part of this URL which have been encoded,<br>
* or <code>null</code> if the user's message isn't defined
*/
public String getPassword() {
return password;
}
/**
* Set the password of URL. <br>
* password will be encoded.
*
* @param password the password of URL.
*/
public void setPassword(String password) {
if (password != null && password.length() != 0)
this.password = encodeString(password);
else
this.password = null;
}
/**
* Get the escaped fragment and query message of the appointed URL path.<br>
* The fragment begin with '#', and the query begin with '?'. <br>
* For the characters of URL which has been encoded to fit the HTTP protocol,<br>
* the decoding operation should be done to get the original characters.
*
* @return the fragment and query message
*/
public String getEscapedPathQuery() {
String escaped = new String();
escaped += path;
if (fragment != null && fragment.length() != 0) {
escaped += "#";
escaped += fragment;
}
if (query != null && query.length() != 0) {
escaped += "?";
escaped += query;
}
return escaped;
}
/**
* Judge whether the URL is valid.
*
* @return <code>true</code> for valid, or <code>false</code> for invalid
*/
public boolean isValid() {
return isValid;
}
public String toString() {
String url = buildString();
URL u = new URL(url);
if (u.isValid())
return url;
else
return null;
}
private String buildString() {
if (hostName == null || hostName.length() == 0)
return null;
String url = "";
if (schema != null && schema.length() != 0)
url = schema+"://";
if (userName != null && userName.length() != 0) {
url += userName;
url += ":";
if (password != null && password.length() != 0) {
url += password;
}
url += "@";
}
url += hostName;
if (port > 0) {
url += ":";
url += port;
}
String escapedPathQuery = getEscapedPathQuery();
if (escapedPathQuery != null && escapedPathQuery.length() != 0)
url += escapedPathQuery;
return url;
}
}
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HttpMidlet extends MIDlet implements CommandListener {
//public static String defaultURL = "http://wap.12530.com";
//public static String defaultURL = "http://wap.monternet.com";
// public static String defaultURL = "http://wap.monternet.com";
//public static String defaultURL = "http://www.lothar.com/pub/";
//public static String defaultURL = "http://218.200.160.29/w/ch/100010/9649?ut=&qd=1580&pc=zj";
//public boolean isCMWAP = false;
public boolean isCMWAP = true;
public Display myDisplay = null;
public boolean doing = false;
public Form requestScreen;
public TextField requestField;
public List list;
public String[] menuItems;
public Form resultScreen;
// public TextField resultField;
public StringItem resultField;
public TextField resultStatus, resultUrl;
Command sendCommand;
Command exitCommand;
Command backCommand;
HttpClient httpClient;
public HttpMidlet(){
myDisplay = Display.getDisplay( this );
sendCommand = new Command("鍙戦��", Command.OK, 1);
exitCommand = new Command("閫�鍑�", Command.OK, 1);
backCommand = new Command("杩斿洖", Command.OK, 1);
requestScreen = new Form("鍖椾含娆㈣繋浣狅紒");
requestField = new TextField("浠嬬粛:", "浠庣Щ鍔ㄦⅵ缃戠殑瀹氬埗褰╅搩銆愭摝鑲╄�岃繃銆�", 256, TextField.URL);
requestScreen.append(requestField);
requestScreen.addCommand(sendCommand);
requestScreen.addCommand(exitCommand);
requestScreen.setCommandListener(this);
menuItems = new String[] {"GET 璇锋眰", "POST 璇锋眰"};
list = new List("璇烽�夋嫨Http鏂规硶:", List.IMPLICIT, menuItems, null);
list.setCommandListener(this);
resultScreen = new Form("鏈嶅姟鍣ㄥ搷搴�:");
resultScreen.addCommand(backCommand);
resultScreen.setCommandListener(this);
resultUrl = new TextField("褰撳墠璇锋眰URL:", null, 256, TextField.ANY);
resultStatus = new TextField("鐘舵��:", null, 300,TextField.ANY);
// resultField = new TextField("鍐呭:", null, 400,TextField.ANY);
resultField = new StringItem("鍐呭:", null, StringItem.PLAIN);
resultScreen.append(resultUrl);
resultScreen.append(resultStatus);
resultScreen.append(resultField);
}
public void startApp() {
myDisplay.setCurrent( requestScreen );
}
public void commandAction( Command com, Displayable disp ) {
if ( com == sendCommand ) {
myDisplay.setCurrent( list );
} else if ( com == backCommand ) {
if (this.doing)
return;
myDisplay.setCurrent( requestScreen );
} else if ( com == exitCommand ) {
destroyApp( true );
notifyDestroyed();
}
if ( disp == list && com == List.SELECT_COMMAND ) {
if (this.doing)
return;
this.doing = true;
httpClient = new HttpClient(this);
httpClient.request(list.getSelectedIndex());
}
}
public void pauseApp() {
}
public void destroyApp( boolean unconditional ) {
myDisplay = null;
requestScreen = null;
requestField = null;
resultScreen = null;
resultField = null;
httpClient = null;
}
}
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
public class HttpClient extends Thread {
static final String LT_GO_HREF = "<go href=";
static final String LT_A_HREF = "<a href=";
static final String DOUBLE_QUOTE = "\"";
static final String SINGLE_QUOTE = "\'";
static Task TASK_NULL = new Task(null, null, null, null, true);
Vector taskStack;
int stackIdx;
HttpMidlet midlet;
int method;
boolean jump;
public HttpClient(HttpMidlet aMidlet) {
midlet = aMidlet;
}
public Task getTask() {
return (Task)taskStack.elementAt(stackIdx);
}
public Task getNextTask() {
return (Task)taskStack.elementAt(stackIdx+1);
}
public void run() {
do {
String result = null;
Task t = getTask();
midlet.resultUrl.setString(t.url);
if (t == TASK_NULL)
break;
if (t.url == null || t.url.length() == 0) {
stackIdx ++;
continue;
}
System.gc();
jump = false;
if (0 == method)
result = sendHttpGet(t.url);
else
result = sendHttpPost(t.url);
if (result != null) {
//midlet.requestField.setMaxSize(result.length());
//midlet.resultField.setString(result);
midlet.resultField.setText(result);
}
if (stackIdx < taskStack.size()-1) {
if (result != null && t.tag != null && t.tag.length() > 0) {
String url = getJumpUrl(result);
if(stackIdx == 4) {
midlet.resultStatus.setString(url);
}
jump = (url != null);
if (jump) {
Task nt = getNextTask();
nt.url = url;
stackIdx++;
}
else {
url = getHoldupUrl(result);
if (jump = (url != null)) {
t.url = url;
}
}
}
else {
stackIdx++;
}
}
/*try {
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
} while(jump);
midlet.doing = false;
}
public void request(int aMethod) {
method = aMethod;
//midlet.resultField.setString("");
midlet.resultField.setText("");
midlet.resultStatus.setString("姝e湪澶勭悊璇锋眰锛岃绋嶅��...");
midlet.myDisplay.setCurrent(this.midlet.resultScreen);
stackIdx = 0;
taskStack = new Vector();
//taskStack.addElement(new Task("http://wap.kong.net", "鍥鹃搩"));
//taskStack.addElement(new Task(null, "姘歌繙鏄綘澶х埛"));
//taskStack.addElement(new Task("http://www.lothar.com/pub/", "text/html", "href=",null, true));
/*taskStack.addElement(new Task("http://wap.12530.com", "鐐瑰嚮姝ゅ", LT_A_HREF, null, false));
taskStack.addElement(new Task(null, "涓嶅樊閽�", LT_A_HREF, null, true));
taskStack.addElement(new Task(null, "here</a>", LT_A_HREF, null, true));
taskStack.addElement(new Task(null, "涓嶅樊閽�", LT_A_HREF, null, true));
taskStack.addElement(new Task(null, "<postfield name=\'", "<go method=\'get\' href=", "&pid=3&sub=0&fee=3.50&bizcode=600906002000005001", false));
taskStack.addElement(new Task(null, "鐐瑰嚮姝ゅ", LT_A_HREF, null, true));*/
taskStack.addElement(new Task("http://wap.12530.com", "鐐瑰嚮姝ゅ", LT_A_HREF, null, false));
taskStack.addElement(new Task(null, "鍚嶄汉涓撶敤閾�", LT_A_HREF, null, true));
taskStack.addElement(new Task(null, "绔嬪嵆杩涘叆", LT_A_HREF, null, true));
taskStack.addElement(new Task(null, "璁㈠埗褰╅搩", LT_A_HREF, null, false));
//taskStack.addElement(new Task(null, "涓嶅樊閽�", LT_A_HREF, null, true));
//taskStack.addElement(new Task(null, "<postfield name=\'", "<go method=\'get\' href=", "&pid=3&sub=0&fee=3.50&bizcode=600906002000005001", false));
//taskStack.addElement(new Task(null, "鐐瑰嚮姝ゅ", LT_A_HREF, null, true));
//taskStack.addElement(new Task(null, "绔嬪嵆杩涘叆", LT_A_HREF, null, true));
//taskStack.addElement(new Task(null, "璁㈠埗褰╅搩", LT_A_HREF, null, false));
taskStack.addElement(new Task(null, null, null, null, true));
taskStack.addElement(TASK_NULL);
// start thread.
start();
}
public String getHoldupUrl(String aPage) {
if (aPage != null && aPage.length()>0) {
Task t = getTask();
String lt_go_href_quto = LT_GO_HREF + (t.doubleQuote ? DOUBLE_QUOTE : SINGLE_QUOTE);
int pos = aPage.indexOf(lt_go_href_quto);
if (pos >= 0) {
pos += lt_go_href_quto.length();
int pos2 = 0;
if ((pos2 = aPage.indexOf(t.doubleQuote ? DOUBLE_QUOTE : SINGLE_QUOTE, pos+1)) > 0)
return aPage.substring(pos, pos2);
else
return aPage.substring(pos);
}
}
return null;
}
public String getJumpUrl(String aPage) {
Task t = getTask();
if (t.hrefSpell != null && aPage != null && aPage.length()>0) {
String href_quto = t.hrefSpell + (t.doubleQuote ? DOUBLE_QUOTE : SINGLE_QUOTE);
int pos;
if ((pos = aPage.indexOf(t.tag)) > 0) {
boolean found = false;
char ch = href_quto.charAt(0);
do {
if ((pos = aPage.lastIndexOf(ch, pos-1)) > 0) {
String hrefSpell = aPage.substring(pos, pos+t.hrefSpell.length());
if (hrefSpell.equalsIgnoreCase(t.hrefSpell)) {
found = true;
pos = aPage.indexOf(href_quto, pos);
}
}
} while(!found && pos >= 0);
}
else {
midlet.resultUrl.setString("jumpUrl: can't found in this page.");
return null;
}
if (pos > 0) {
pos += href_quto.length();
int pos2 = aPage.indexOf(t.doubleQuote ? DOUBLE_QUOTE : SINGLE_QUOTE, pos+1);
String tmp = null;
if (pos2>0)
tmp = aPage.substring(pos, pos2);
else
tmp = aPage.substring(pos);
StringBuffer buf = new StringBuffer();
int len = tmp.length();
for (int i=0; i < tmp.length(); i++) {
if (i+5<=len && tmp.charAt(i) == '&'
&& tmp.charAt(i+1) == 'a'&& tmp.charAt(i+2) == 'm'
&& tmp.charAt(i+3) == 'p' && tmp.charAt(i+4) == ';') {
i += 4;
buf.append('&');
}
else
buf.append(tmp.charAt(i));
}
String jumpUrl = buf.toString();
if (jumpUrl.indexOf("://") < 0) {
URL uu = new URL(t.url);
if (jumpUrl.charAt(0) == '/' || jumpUrl.charAt(0) == '\\') {
jumpUrl = uu.getSchema()+"://"+uu.getHostName() + jumpUrl;
}
else {
char ch = uu.getPath().charAt(uu.getPath().length()-1);
if (ch == '/' || ch == '\\')
jumpUrl = uu.getSchema()+"://"+uu.getHostName()+uu.getPath()+jumpUrl;
else
jumpUrl = uu.getSchema()+"://"+uu.getHostName()+uu.getPath()+"/"+jumpUrl;
}
}
System.gc();
if (t.query != null && t.query.length()>0) {
jumpUrl += t.query;
}
return jumpUrl;
}
}
return null;
}
public String getCharsetValue(final String line) {
if (line != null && line.length() > 0) {
final String charset = "charset=";
int pos = line.indexOf(charset);
if (pos >= 0) {
pos += charset.length();
int pos2 = line.indexOf(';', pos+1);
String value = null;
if (pos2>0)
value = line.substring(pos, pos2);
else
value = line.substring(pos);
return value;
}
}
return null;
}
private boolean isTextMIME(String type) {
if (type == null || type.length() == 0)
return true;
return type.startsWith("text/");
}
public String sendHttpGet(String url) {
HttpConnection hcon = null;
InputStream is = null;
try {
URL u = new URL(url);
if (!u.isValid()) {
//midlet.resultField.setString("鏃犳晥URL:\n"+url);
midlet.resultField.setText("鏃犳晥URL:\n+url");
return null;
}
String fixedurl = url;
if (midlet.isCMWAP) {
fixedurl = "http://10.0.0.172" + u.getEscapedPathQuery();
}
hcon = (HttpConnection)Connector.open(fixedurl);
fixedurl = null;
if (midlet.isCMWAP) {
hcon.setRequestProperty("X-Online-Host", u.getHostName()+":"+u.getPort());
}
hcon.setRequestProperty("Host", u.getHostName()+":"+u.getPort());
hcon.setRequestProperty("Accept", "*/*");
int len = (int)hcon.getLength();
byte data[] = null;
String encoding;
if ((encoding = hcon.getEncoding()) == null) {
encoding = getCharsetValue(hcon.getType());
}
System.gc();
String status = "FreeMem: "+Runtime.getRuntime().freeMemory();
status += "\nHTTP " + hcon.getResponseCode() + " " + hcon.getResponseMessage();
status += "\nContent-Length=" + hcon.getLength();
status += "\nContent-Type=" + hcon.getType();
status += "\nEncoding=" + encoding;
midlet.resultStatus.setString(status);
is = hcon.openInputStream();
if (!isTextMIME(hcon.getType())) {
int num = 0;
while((is.read()) != -1) {
num++;
//midlet.resultField.setString("鏀跺埌瀛楄妭鏁帮細"+num);
midlet.resultField.setText("鏀跺埌瀛楄妭鏁帮細"+num);
}
if (hcon != null) hcon.close();
if (is != null) is.close();
return null;
}
if (len > 0) {
int num = 0;
data = new byte[len];
while ((num != len)
&& (is.read(data, num, len-num)) != -1) {
}
}
else {
if (len == -1 && 200 == hcon.getResponseCode()) {
Vector vbuf = new Vector();
int ch;
while((ch = is.read()) != -1) {
vbuf.addElement(new Integer(ch));
}
len = vbuf.size();
data = new byte[len];
for(int i = 0; i < len; i++) {
data[i]=((Integer)vbuf.elementAt(i)).byteValue();
}
}
}
if (hcon != null) hcon.close();
if (is != null) is.close();
System.gc();
if (data != null)
return new String(data, encoding == null ? "UTF-8" : encoding);
}
catch(Exception e) {
e.printStackTrace();
// midlet.resultField.setString(e.getMessage());
}
finally {
try {
if (hcon != null) hcon.close();
if (is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
// midlet.resultField.setString(e.getMessage());
}
}
try {
if (hcon != null) hcon.close();
if (is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
// midlet.resultField.setString(e.getMessage());
}
return null;
}
public String sendHttpPost(String url) {
return null;
}
}
以后有时间排版, 上面是代码。 下面是文档, 有空再整理啦
在开始写这篇技术文档钱,非常令人郁闷。在blog上写了两次都被不小心的Ctrl+W误操作给销毁了。 特别是第一次, 都快要写完了。这次的事故给了我一个很深刻的提醒,以后写技术博客, 要先在word文档中写好草稿, 然后在发布。
好了,开始进入这次的主题。
触发写这篇博客的动机是, 今天闲着无聊去逛人才市场。查看最新人才需求动向。当时我与一个面试官在进行技术交流。在聊到网络编程方面,他老是提到一个技术术语--C网。当时就被问蒙了,我接触J2ME也有1年半了。对于GCF框架也有很深刻的认识,但是还从来没有分析过C网与HTTP联网的关系。虽然在公司常听到前辈们谈起C网, G网, 3G等。但只是很肤浅的认识这些东东。于是今天就从操作系统一直到J2ME层次,来分析一下手机移动的联网。
在谈论网络联网,那么我们首先必须要牵涉到一个计算机的术语:Socket。在计算机进入我们人类社会中,最开始的阶段还是没有联网的功能的。某一天,美国的某某某突发冥想,两台在不同区域的电脑能不能进行通讯,进行资源的共享呢?在他尝试成功之后,也就有了我们现在广泛使用的的Internet、Intranet等等。
对于操作系统来说,它提供了最基本的网络服务:Socket。也就是软件工程师口中常说的套接字。对于一切的平台都是通过套接字来进行网络的通信的。无论是PC平台,STB平台或嵌入式平台,联网都需要具有Socket服务模块(这里我当你了解Socket编程原理的,如果不清楚的读者,建议赶紧去充电)。在手机平台中,主流有的操作系统有:WIN CE, WIN MOBILE, SYSBIAN, MTK。这些据我了解都是有Socket模块的。
对于联网的编程, 协议必须要遵守的。假如我们通过Socket进行联网,全球各自遵循不同的标准进行网络通讯。那么网络的通讯将会无比庞大并且不可维护。就如我们古人说的:无规矩不成方圆。所以还是要定一套进行网络通讯的标准的。
最开始出台的是国际标准化组织(International Organization for Standardization)制定的网络七层协议理论参考模型(OSI)。但是由于太过于复杂!美国的文顿·瑟夫和卡恩两位骚包人物提出了TCP/IP协议的规范!于是就风靡全球,成了Internet的准标准协议。
操作系统提供Socket进行网络数据的传输模式,而TCP/IP协议对网络中传输的数据格式进行了规范的定义。于是就形成了一套完整的数据通信。
这样我们就可以在操作系统层之上就行网络互联方面的应用开发了。
对于J2ME来说, 它只是JAVA家族中的一个微型版本,主要用于嵌入式方面的开发。它的架构也就是在手机的操作系统使用C开发一个虚拟机,然后通过包装原始的Socket, 在Java层面提供一套网络的访问接口,进行网络的通信。J2ME层提供的是比较安全的GCF框架的网络通信。JSR要求J2ME至少要提供HTTP协议的支持。
谈到这里,我们现在大致知道了J2ME联网的一个流程。现在我们来了解一下CNWap和CNNet的信息
以下信息来自于百度知道:
*****************以下信息来自于百度知道:*********************************
cmwap和cmnet,这是移动提供的两个不同的接入点。CMWAP 和 CMNET 只是移动人为划分的两个GPRS接入方式。前者是为手机WAP上网而设立的,后者则主要是为PC、笔记本电脑、PDA等利用GPRS上网服务。它们在实现方式上并没有任何差别,但因为定位不同,所以和CMNET相比,CMWAP便有了部分限制,资费上也存在差别。
WAP只是一种GPRS应用模式,它与GRPS的接入方式是无关的。WAP应 用采用的实现方式是“终端+WAP网关+WAP服务器”的模式,不同于一般Internet的“终端+服务器”的工作模式。主要的目的是通过WAP网关完成WAP-WEB的协议转换以达到节省网络流量和兼容现有WEB应用的目的。WAP网关从技术的角度讲,只是一个提供代理服务的主机,它不一定由网络运营商提供。移动GPRS网络目前只有唯一的一个WAP网关:10.0.0.172,由移动提供,用于WAP浏览(HTTP)服务。
有一点需要注意,WAP网关和一般意义上的局域网网关是有差别的,标准的WAP网关仅仅实现了HTTP代理的功能,并未完成路由、NAT等局域网网关的功能。这就决定了它在应用上所受到的限制。
为了从应用中区别两者的定位,移动对CMWAP作了一定的限制,主要表现在CMWAP接入时只能访问GPRS网络内的IP(10.*.*.*),而无法通过路由访问Internet。我们用CMWAP浏览Internet上的网页就是通过WAP网关协议或它提供的HTTP代理服务实现的。也就是需要通过移动GPRS网络唯一的一个WAP网关:10.0.0.172。因为有了上面提到的限制,CMWAP的适用范围就要看WAP网关所提供的支持了。目前,移动的WAP网关对外只提供HTTP代理协议(80和8080端口)和WAP网关协议(9201端口)。
因此,只有满足以下两个条件的应用才能在移动的CMWAP接入方式下正常工作:1. 应用程序的网络请求基于HTTP协议。2. 应用程序支持HTTP代理协议或WAP网关协议。而cmnet则不受任何的限制。
其实就是说通过cmwap的方式访问,需要走移动的网关通过http协议去连接,这样的后果就是速度会变慢,相信很多朋友都用过代理服务器吧,对,就是那个感觉,而通过cmnet来连接的,就是直接连接到在internet上的服务器,速度会比cmwap的快一些。
说完了速度,就该说价格了,如果玩家没有采用套餐的话,那cmwap和cmnet都是一样的,1k三分钱,或者订了一个xx元包xM的套餐,超出部分1k一份钱,这种时候,同等价格都一样,据我了解,cmwap版本流量会大一些,所以还是用cmnet比较好,又快又省钱。但是对于很多地方的动感地带用户而言,情况可能有些不同,相当一些地方的动感地带只能访问cmwap,不能访问cmnet,所以没地选择了,还有一些地方有动感地带的包月上网卡,有10元、20元、50元的等等,具体的要看当地的资费政策了,而这些包月卡通常只包cmwap的流量,这个时候如果用cmnet还要另外付费,所以建议这些用户还是使用cmwap吧。
总结一下CMWAP下可以使用的常见软件的工作方式:
(1) 手机内置的浏览器:WAP网关协议
(2) Opera 浏览器:HTTP代理协议(有代理设置)
(3) Java 程序:WAP网关协议
(4) AvantGo:HTTP代理协议(有代理设置)
**************************************************************************
OK! 看完了上面的信息, 我们对移动价格方面的策略不做评论(听说在国外移动只有一种形式的GPRS)。
满足以下两个条件的应用才能在移动的CMWAP接入方式下正常工作:1. 应用程序的网络请求基于HTTP协议。2. 应用程序支持HTTP代理协议或WAP网关协议。而cmnet则不受任何的限制。
这个是我们重点需要知道的。
现在我们来分析j2me层的联网代码
在进行联网的开发前, 必须知道终端手机的联网模式。
我以www.sina.com来说明问题:
在CNNET模式下:联网的代码:
HttpConnection httpConnection = (HttpConnection)Connector.open(“www.sina.com”);
在CNWAP模式下:联网的代码:
HttpConnection httpConnection = (HttpConnection)Connector.open(“http://10.0.0.172:80/”);
接着再写
httpConnection.setRequestProperty("X-Online-Host", www.testwap.com");
httpConnection.setRequestProperty("Accept","*/*");
其实,说白了, 就是先将HTTP的消息发送到10.0.0.172:80的服务器,然后通过它解析HTTP包的意思, 最后将我们的请求发送到www.sina.com服务器请求服务。
NOTE: CNWAP不支持Socket连接, CNNet支持Socket连接
下面是我写的一段J2ME的一个实例代码:
现在还有一个问题,就是人们常说C网的术语。
C网只是说明了手机支持的频段。
***************************以下信息来自于百度知道************************************
提到手机支持频段,首先应明确频段实质上是硬性划分的,这主要是由于频率资源的有限导致, 目前我国主要由信息产业部负责相关事宜。
我国手机常用的频段主要有CDMA手机占用的CDMA1X,800MHZ频段;GSM手机占用的900/1800/1900MHZ 频段;近两年的GSM1X双模占用的900/1800MHZ频段;3G占用的900/1800/1900/2100MHz频段。
GSM频段:我国GSM手机占用频段主要是900MHZ和1800MHZ。实质上1800MHZ也是由于手机用户数量 的激增,造成了手机通信网络系统处于超负荷运转状态,最终导致了手机在通信时很容易出现类似于 掉线、串音、话音质量不好、难以上网等故障现象。为了解决这些故障现象,越来越多的手机运营商 和生产商开始意识到解决这个问题的迫切性,并不断采取相关措施来进一步扩容手机网络系统,于是 GSM1800Mhz便应运而生了,又被称为DCS1800(数字蜂窝系统),它的出现,使基于GSM900、1800的 双频网络变为现实。