CNWap,CNNet, J2ME联网漫谈

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。在计算机进入我们人类社会中,最开始的阶段还是没有联网的功能的。某一天,美国的某某某突发冥想,两台在不同区域的电脑能不能进行通讯,进行资源的共享呢?在他尝试成功之后,也就有了我们现在广泛使用的的InternetIntranet等等。

对于操作系统来说,它提供了最基本的网络服务: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联网的一个流程。现在我们来了解一下CNWapCNNet的信息
以下信息来自于百度知道:
 
*****************以下信息来自于百度知道:*********************************
cmwapcmnet,这是移动提供的两个不同的接入点。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网络内的IP10.*.*.*),而无法通过路由访问Internet。我们用CMWAP浏览Internet上的网页就是通过WAP网关协议或它提供的HTTP代理服务实现的。也就是需要通过移动GPRS网络唯一的一个WAP网关:10.0.0.172。因为有了上面提到的限制,CMWAP的适用范围就要看WAP网关所提供的支持了。目前,移动的WAP网关对外只提供HTTP代理协议(808080端口)和WAP网关协议(9201端口)。
因此,只有满足以下两个条件的应用才能在移动的CMWAP接入方式下正常工作:1. 应用程序的网络请求基于HTTP协议。2. 应用程序支持HTTP代理协议或WAP网关协议。而cmnet则不受任何的限制。
其实就是说通过cmwap的方式访问,需要走移动的网关通过http协议去连接,这样的后果就是速度会变慢,相信很多朋友都用过代理服务器吧,对,就是那个感觉,而通过cmnet来连接的,就是直接连接到在internet上的服务器,速度会比cmwap的快一些。
说完了速度,就该说价格了,如果玩家没有采用套餐的话,那cmwapcmnet都是一样的,1k三分钱,或者订了一个xx元包xM的套餐,超出部分1k一份钱,这种时候,同等价格都一样,据我了解,cmwap版本流量会大一些,所以还是用cmnet比较好,又快又省钱。但是对于很多地方的动感地带用户而言,情况可能有些不同,相当一些地方的动感地带只能访问cmwap,不能访问cmnet,所以没地选择了,还有一些地方有动感地带的包月上网卡,有10元、20元、50元的等等,具体的要看当地的资费政策了,而这些包月卡通常只包cmwap的流量,这个时候如果用cmnet还要另外付费,所以建议这些用户还是使用cmwap吧。
总结一下CMWAP下可以使用的常见软件的工作方式:
 
  (1) 手机内置的浏览器:WAP网关协议
  (2) Opera 浏览器:HTTP代理协议(有代理设置)
  (3) Java 程序:WAP网关协议
  (4) AvantGoHTTP代理协议(有代理设置)
 

**************************************************************************

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手机占用的CDMA1X800MHZ频段;GSM手机占用的900/1800/1900MHZ 频段;近两年的GSM1X双模占用的900/1800MHZ频段;3G占用的900/1800/1900/2100MHz频段。

GSM频段:我国GSM手机占用频段主要是900MHZ1800MHZ。实质上1800MHZ也是由于手机用户数量 的激增,造成了手机通信网络系统处于超负荷运转状态,最终导致了手机在通信时很容易出现类似于 掉线、串音、话音质量不好、难以上网等故障现象。为了解决这些故障现象,越来越多的手机运营商 和生产商开始意识到解决这个问题的迫切性,并不断采取相关措施来进一步扩容手机网络系统,于是 GSM1800Mhz便应运而生了,又被称为DCS1800(数字蜂窝系统),它的出现,使基于GSM9001800 双频网络变为现实。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值