<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    騎豬闖天下

    J2ME隨筆,記錄成長的腳步

    統(tǒng)計

    留言簿(3)

    閱讀排行榜

    評論排行榜

    [J2ME] 無線網(wǎng)絡(luò)開發(fā)

    無線網(wǎng)絡(luò)開發(fā)


    MIDP提供了一組通用的網(wǎng)絡(luò)開發(fā)接口,用來針對不同的無線網(wǎng)絡(luò)應(yīng)用可以采取不同的開發(fā)接口。基于CLDC的網(wǎng)絡(luò)支持是由統(tǒng)一網(wǎng)絡(luò)連接框架(Generic Connection Frameword, 簡稱GCF)定義的。其相關(guān)類、接口以及異常都放置在javax.microedtion.io包中。
    在CLDC之中定義了七個接口,它們分別是:
    1. Connection
    2. StreamConnectionNotifier
    3. InputConnection
    4. OutputConnection
    5. DatagramConnection
    6. StreamConnection
    7. ContentConnection
    直接繼承自Connection的有四個類:StreamConnectionNotifier、DatagramConnection、InputConnection和OutputStream。其中,StreamConnectionNotifier只要提供Socket開發(fā)接口。DatagramConnection提供UDP開發(fā)接口。由于需要對網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)輸入和輸出進(jìn)行控制,因此提供了InputConnection和OutputConnection開發(fā)接口。
    通用的網(wǎng)絡(luò)開發(fā)接口都是繼承自Connection接口。
    GCF繼承體系
    MIDP2.0中,新添加了3個網(wǎng)絡(luò)開發(fā)接口:
    ?? javax.microedition.io.SocketConnection 負(fù)責(zé)TCP/IP方面的網(wǎng)絡(luò)開發(fā)
    ?? javax.microedition.io.ServerSocketConnection 負(fù)責(zé)TCP/IP方面的網(wǎng)絡(luò)開發(fā)
    ?? javax.microedition.io.UDPDatagramConnection 負(fù)責(zé)UDP方面的開發(fā)
    網(wǎng)絡(luò)開發(fā)中,最重要的一個連接類是HttpConnection接口, 其繼承自ContentConnection。HttpConnection中定義了大量的基本聯(lián)網(wǎng)和獲取數(shù)據(jù)的操作。Http聯(lián)網(wǎng)功能是MIDP規(guī)范中要求廠商必須支持的連接方式,而其它方式,則取決于廠商與網(wǎng)絡(luò)服務(wù)商的設(shè)備支持情況。
    也就是說,只有HTTP傳輸協(xié)議才是能夠在各家平臺上使用的對外溝通的方式。
    GCF規(guī)范提出不管使用何種網(wǎng)絡(luò)或者本地文件的連接方式,所有的連接都使用Connector的open(URL)方法創(chuàng)建一個新的網(wǎng)絡(luò)連接(Connection.open(url)方法將返回一個Connection對象):
    URL的格式如下;
    <協(xié)議>://<用戶名>:<密碼>@<資源所在主機>:<端口號>/<資源路徑>;<參數(shù)>
    協(xié)議如: http、https、socket方式等。資源所在主機代表資源所在位置的主機名稱或者IP地址。資源路徑的格式和使用的協(xié)議有關(guān),有些協(xié)議會有額外的參數(shù)需要設(shè)定。
    1) 創(chuàng)建Http連接
    Connector.open(“http://www.sun.com.cn”);
    2) 創(chuàng)建Socket連接
    Connector.open(“socket://127.0.0.1:8080”);
    3) 創(chuàng)建Datagram連接
    Connector.open(“datagram://www.sun.com.cn:9000”);
    4) 創(chuàng)建本地文件連接
    Connector.open(“file:/input.txt”);
    Connector.open()方法有3個重載的方法:
    public static Connection open(String name)
    public static Connection open(String name, int mode)
    public static Connection open(String name, int mode, Boolean timeout)
    參數(shù):
    name指定網(wǎng)絡(luò)地址
    mode指定網(wǎng)絡(luò)連接的方式,分為讀、寫和讀寫三種方式
    timeout指定了網(wǎng)絡(luò)連接超時的時間。如果網(wǎng)絡(luò)連接超時,則拋出異常
    一、 MIDP開發(fā)HTTP程序
    使用Connector.open()方法獲得一個網(wǎng)絡(luò)連接以后,就可以調(diào)用相應(yīng)的Connection類的方法獲得需要的信息。
    利用Connection的openInputStream()方法可以獲得網(wǎng)絡(luò)傳輸過來的流數(shù)據(jù)。
    (一) 使用StreamConnection接口
    StreamConnection接口繼承了InputConnection和OutputConnection接口,因此創(chuàng)建一個StreamConnection對象可以返回一個獲得網(wǎng)絡(luò)傳輸數(shù)據(jù)的流對象,可以使用返回的流對象對數(shù)據(jù)進(jìn)行整理,再選取需要的數(shù)據(jù)顯示在屏幕上。
    流程如下:
    1. 創(chuàng)建一個StreamConnection類型的網(wǎng)絡(luò)連接
    StreamConnection sc = null;
    sc = (StreamConnection)Connector.open(url);
    2. 創(chuàng)建了StreamConnection類型的網(wǎng)絡(luò)連接以后,可以調(diào)用openInputStream()方法返回一個InputStream對象,通過該對象獲得流數(shù)據(jù)。也可以使用openDataInputStream()方法返回一個DataInputStream對象。
    InputStream is = null;
    is = sc.openInputStream();
    3. 通過數(shù)據(jù)對象操作獲得的數(shù)據(jù):
    StringBuffer sb = new StringBuffer();
    int ch;
    while ((ch = is.read()) != -1)
    {
    sb.append((char)ch);
    }
    System.out.println(sb.toString());
    4. 操作數(shù)據(jù)完成,關(guān)閉連接對象。
    is.close();
    練習(xí):用StreamConnection實現(xiàn)讀取網(wǎng)頁內(nèi)容。
    (二) 使用HttpConnection接口
    使用HttpConnection接口的開發(fā)流程與使用StreamConnection接口基本一樣。由于HttpConnection接口繼承了StreamConnection接口,不但擁有StreamConnection接口的功能,還擴展了許多功能。
    例:
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.io.*;
    import java.io.*;
    /**
    *
    * @author Allan
    * @version
    */
    public class HttpConnectionMidlet extends MIDlet
    {
    private Display display;
    public HttpConnectionMidlet()
    {
    display = Display.getDisplay(this);
    }
    public void startApp()
    {
    TextBox tb = new TextBox("Browser", "", 10000, TextField.ANY);
    String url = " HttpConnection hc = null;
    try
    {
    hc = (HttpConnection)Connector.open(url);
    InputStream is = hc.openInputStream();
    StringBuffer sb = new StringBuffer();
    int ch;
    while ((ch = is.read()) != -1)
    {
    sb.append((char)ch);
    }
    //System.out.println(sb.toString());
    tb.setString(sb.toString());
    display.setCurrent(tb);
    }
    catch (Exception e)
    {
    }
    finally
    {
    if (hc != null)
    {
    try
    {
    hc.close();
    }
    catch (Exception e)
    {
    }
    }
    }
    }
    public void pauseApp()
    {
    }
    public void destroyApp(boolean unconditional)
    {
    }
    }
    (三) 顯示服務(wù)器信息
    HttpConnection接口提供了多個獲得服務(wù)器信息的方法。
    獲得了一個HttpConnection的連接對象以后,不需要使用openInputStream()方法就可以直接返回服務(wù)器信息(訪問資源的信息)。
    例:
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.io.*;
    import java.io.*;
    /**
    *
    * @author Administrator
    * @version
    */
    public class ServerInfoMidlet extends MIDlet
    {
    private Display display;
    public ServerInfoMidlet()
    {
    display = Display.getDisplay(this);
    }
    public void startApp()
    {
    Form f = new Form("");
    String url = "
    HttpConnection hc = null;
    StringBuffer sb = new StringBuffer();
    try
    {
    hc = (HttpConnection)Connector.open(url);
    //要顯示的服務(wù)器的信息
    sb.append("Host: " + hc.getHost());
    sb.append("\nPost: " + hc.getPort());
    sb.append("\nDate: " + hc.getDate());
    sb.append("\nProtocol: " + hc.getProtocol());
    sb.append("\nFile: " + hc.getFile());
    sb.append("\nType: " + hc.getType());
    //在屏幕上顯示信息
    f.append(sb.toString());
    display.setCurrent(f);
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    finally
    {
    if (hc != null)
    {
    try
    {
    hc.close();
    }
    catch (Exception e)
    {
    }
    }
    }
    }
    public void pauseApp()
    {
    }
    public void destroyApp(boolean unconditional)
    {
    }
    }
    (四) HTTP連接方式的簡單應(yīng)用
    1. 下載觀看圖片
    從網(wǎng)絡(luò)上下載圖片是通過二進(jìn)制數(shù)據(jù)傳輸?shù)模虼丝梢允褂肐mage的重載方法:
    Image createImage(byte[] imageData, int imageOffset, int imageLength)
    Image createImage(InputStream stream) MIDP2.0提供
    將圖片的數(shù)據(jù)存儲到字節(jié)數(shù)組imageData或者輸入流對象stream中,就可以使用createImage()方法將它們轉(zhuǎn)換為Image對象,以便在屏幕上顯示出來。
    使用方法1:
    import javax.microedition.lcdui.*;
    import javax.microedition.io.*;
    import java.io.*;
    /**
    *
    * @author Allan
    */
    public class MyForm extends Form implements CommandListener, Runnable
    {
    private TextField tfUrl;
    //下載的圖像
    private ImageItem iiImage;
    public MyForm()
    {
    super("");
    tfUrl = new TextField("圖片地址", "", 100, TextField.URL);
    iiImage = new ImageItem("Image", null, Item.LAYOUT_CENTER, "圖片位置");
    iiImage.setPreferredSize(getWidth(), 100);
    append(tfUrl);
    append(iiImage);
    addCommand(new Command("下載", Command.OK, 1));
    setCommandListener(this);
    }
    public Image getImage(String url)
    {
    HttpConnection hc = null;
    //供返回的image對象
    Image image = null;
    try
    {
    hc = (HttpConnection)Connector.open(url);
    DataInputStream dis = hc.openDataInputStream();
    byte[] imageData;
    int len = (int)hc.getLength();
    if (len != -1)
    {
    imageData = new byte[len];
    dis.readFully(imageData);
    }
    else
    {
    //未知長度,則按照字節(jié)的方式讀取數(shù)據(jù)
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int ch;
    while ((ch = dis.read()) != -1)
    {
    baos.write(ch);
    }
    imageData = baos.toByteArray();
    baos.close();
    }
    if (dis != null)
    {
    dis.close();
    }
    //根據(jù)二進(jìn)制數(shù)據(jù)創(chuàng)建一個Image
    return Image.createImage(imageData, 0, imageData.length);
    }
    catch (Exception e)
    {
    e.printStackTrace();
    return null;
    }
    finally
    {
    if (hc != null)
    {
    try
    {
    hc.close();
    }
    catch (Exception e)
    {
    }
    }
    }
    }
    public void commandAction(Command c, Displayable s)
    {
    String cmd = c.getLabel();
    if (cmd.equals("下載"))
    {
    new Thread(this).start();
    }
    }
    public void run()
    {
    Image tmp = this.getImage(tfUrl.getString().trim());
    iiImage.setImage(tmp);
    }
    }
    2. 方法二:
    public Image getImage2(String url)
    {
    HttpConnection hc = null;
    //供返回的image對象
    Image image = null;
    try
    {
    hc = (HttpConnection)Connector.open(url);
    //判斷連接是否成功
    if (hc.getResponseCode() != HttpConnection.HTTP_OK)
    {
    return null;
    }
    //取得圖像二進(jìn)制數(shù)據(jù)
    DataInputStream dis = hc.openDataInputStream();
    image = Image.createImage(dis);
    dis.close();
    //根據(jù)二進(jìn)制數(shù)據(jù)創(chuàng)建一個Image
    return image;
    }
    catch (Exception e)
    {
    e.printStackTrace();
    return null;
    }
    finally
    {
    if (hc != null)
    {
    try
    {
    hc.close();
    }
    catch (Exception e)
    {
    }
    }
    }
    }
    (五) 練習(xí):文本文件查看器,選擇保存將其保存到Restor Store中,可供以后觀看。
    (六) 用HTTP方式與服務(wù)器交互信息
    使用Get方式與服務(wù)器交互信息,則具體的開發(fā)流程:
    1. 設(shè)置Get訪問方式的Http地址:
    String url = “http://127.0.0.1:8080/MyTest/hello?username=abc&password=456”;
    2. 創(chuàng)建HttpConnection類型的網(wǎng)絡(luò)連接。
    HttpConnection hc = (HttpConnection)Connector.open(url);
    3. 調(diào)用HttpConnection的setRequestMethod()方法設(shè)置與服務(wù)器交互信息的類型為GET類型:
    hc.setRequestMetho(HttpConnection.GET);
    4. 服務(wù)器獲得請求后,會調(diào)用doGet()方法,但MIDlet并不知道服務(wù)器是否正確獲得請求,可以使用下面語句判斷:
    if (hc.getResponseCode() == HttpConnection.HTTP_OK)
    {
    //讀取服務(wù)器信息
    … …
    }
    5. 讀取信息后,顯示結(jié)果。
    (七) 使用Socket網(wǎng)絡(luò)開發(fā)接口
    MIDP提供了對開發(fā)Socket程序的支持,但是由于Socket程序并不是MIDP2.0中要求移動設(shè)備廠商必須支持的協(xié)議,所以有可能實際應(yīng)用并不能使用,所以需要根據(jù)當(dāng)?shù)氐脑O(shè)備情況進(jìn)行選擇性的開發(fā)。
    1. 什么是Socket? 客戶機/服務(wù)器?
    可以把Socket看成是兩個手機程序進(jìn)行通訊連接中的一個端點,一個程序?qū)⒁欢涡畔懭隨ocket,該Socket將這段信息發(fā)送給另一個Socket中,使這段信息能傳送到另一個手機程序中。
    手機的Socket傳輸方式可以理解為手機的客戶機/手機的服務(wù)器的交流模式。
    客戶機/服務(wù)器在分布處理過程中,使用基于連接的網(wǎng)絡(luò)通信模式。該通信模式首先在客戶機和服務(wù)器之間定義一套通信協(xié)議,并創(chuàng)建一Socket類,利用這個類建立一條可靠的鏈接;然后,客戶機/服務(wù)器再在這條鏈接上可靠地傳輸數(shù)據(jù)。
    客戶機發(fā)出請求,服務(wù)器監(jiān)聽來自客戶機的請求,并為客戶機提供響應(yīng)服務(wù)。這就是典型的“請求——應(yīng)答”模式。
    手機客戶機/服務(wù)器典型運作過程:
    1) 手機服務(wù)器監(jiān)聽響應(yīng)端口的輸入;
    2) 手機客戶機發(fā)出一個請求;
    3) 手機服務(wù)器接收到此請求,處理請求,并把請求結(jié)果返回給手機客戶機;
    4) 重復(fù)上述過程,直至完成一次信息交互過程。
    利用以上過程,可以使用MIDP編寫作為服務(wù)器和客戶機的手機應(yīng)用程序。一個作為服務(wù)器端的手機應(yīng)用程序在負(fù)責(zé)監(jiān)聽另外一個作為客戶機的手機程序的請求,為每個
    作為客戶機請求的手機程序建立Socket連接,從而為作為客戶機的手機程序提供服務(wù)。
    2. 開發(fā)Socket點到點程序
    點到點程序使用的是服務(wù)器、客戶機的“請求——應(yīng)答”模式,所以開發(fā)Socket程序可以分為開發(fā)服務(wù)器端和客戶端程序兩種
    開發(fā)手機服務(wù)器端程序步驟如下:
    步驟一:建立服務(wù)器端的Socket監(jiān)聽端口,監(jiān)聽所有客戶機的連接請求。創(chuàng)建一個具體的連接是使用ServerSocketConnection類來實現(xiàn)的。
    監(jiān)聽端口的字符串格式:
    socket://:port
    由于服務(wù)器從本地端口監(jiān)聽客戶端連接,所以不需要指定本機器的IP地址,只需要指定監(jiān)聽的端口port就可以了。
    創(chuàng)建一個監(jiān)聽端口為8859的ServerSocketConnection的代碼如下:
    String url = “socket://:8859”;
    ServerSocketConnection ssc;
    ssc = (ServerSocketConnection)Connector.open(url);
    步驟二:建立收發(fā)客戶機信息的SocketConnection。ServerSocket僅僅是創(chuàng)建監(jiān)聽端口,具體的信息交流需要通過SocketConnection來實現(xiàn)。可以調(diào)用ServerSocketConnection的acceptAndOpen()方法返回一個SocketConnection類的對象。然后利用這個返回的對象操作客戶端傳來的信息:
    SocketConnection sc;
    sc = (SocketConnection)scc.acceptAndOpen();
    acceptAndOpen()一直監(jiān)聽客戶端是否請求連接服務(wù)器,如果沒有發(fā)現(xiàn)任何請求,則會一直監(jiān)聽,直到有連接請求才會返回一個SocketConnection對象。
    步驟三:可以通過返回的SocketConnection對象設(shè)置服務(wù)器的監(jiān)聽屬性:
    sc.setSocketOption(DELAY, 0); //設(shè)置延遲
    sc.setSocketOption(LINGER, 0); //設(shè)置生存時間
    sc.setSocketOption(KEEPALIVE, 0); //持續(xù)狀態(tài)
    sc.setSocketOption(RCVBUF, 128); //獲得字節(jié)數(shù)
    sc.setSocketOption(SNDBUF, 128); //發(fā)送字節(jié)數(shù)
    步驟四:通過服務(wù)器端監(jiān)聽客戶機連接成功后的SocketConnection對象與客戶機進(jìn)行數(shù)據(jù)的接收和發(fā)送。
    DataInputStream dis = sc.openDataInputStream();
    DataOutputStream dos = sc.openDataOutputStream();
    String result = dis.readUTF();
    dos.writeUTF(result);
    步驟五:關(guān)閉/釋放資源
    dis.close();
    dos.close();
    sc.close();
    ssc.close();
    開發(fā)手機客戶端程序步驟如下:
    步驟一:建立手機客戶端的Socket連接端口,必須指定連接地址,其格式如下:
    socket://主機地址:端口號
    例:
    String url = “socket://127.0.0.1:8859”;
    SocketConnection sc;
    sc = (SocketConnection)Connector.open(url);
    步驟二:利用SocketConnection的read()方法和write()方法接收和發(fā)送數(shù)據(jù)。
    步驟三:釋放各種資源。
    (八) 開發(fā)Datagram程序
    MIDP提供了對Datagram程序的支持,但是由于Datagram程序并不是MIDP2.0中要求移動廠商必須支持的協(xié)議,所以有可能實際應(yīng)用并不能使用,因此像Socket程序的開發(fā)一樣,需要根據(jù)當(dāng)?shù)氐脑O(shè)備情況進(jìn)行選擇性的開發(fā)。
    1、 Datagram是什么?
    Socket是針對TCP/IP協(xié)議開發(fā)的,是一種面向連接的保證可靠傳輸?shù)膮f(xié)議。發(fā)送方與接收方在成對的兩個Socket之間建立連接,以便在TCP基礎(chǔ)上進(jìn)行通信。
    Datagram(數(shù)據(jù)報)則是針對UDP協(xié)議進(jìn)行開發(fā)的,是非面向連接的,不能保證數(shù)據(jù)可靠到達(dá)。
    每個數(shù)據(jù)報都是一個獨立的信息包,包括完整的源地址或目的地址,它在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此能否到達(dá)目的地,到達(dá)目的地的時間以及內(nèi)容的正確性都是不能被保證的。
    使用UDP時,每個數(shù)據(jù)報中都給出了完整的地址信息,因此無需建立發(fā)送方和接收方的連接。
    使用UDP傳輸數(shù)據(jù)時是有大小限制的,每個被傳輸?shù)臄?shù)據(jù)報必須限定在64KB之內(nèi)。而TCP則沒有這方面的限制。
    協(xié)議
    面向連接
    可靠傳輸
    數(shù)據(jù)大小限制
    TCP



    UDP


    64KB
    UDP協(xié)議不可或缺的原因:
    ?? 可靠傳輸需要付出代價,對數(shù)據(jù)內(nèi)容的正確性檢驗占用計算機處理時間和網(wǎng)絡(luò)的帶寬,TCP的傳輸效率不如UDP。
    ?? 許多應(yīng)用程序并不需要嚴(yán)格的傳輸可靠性,比如視頻會議系統(tǒng),并不要求音頻/視頻數(shù)據(jù)的絕對正確,只要保證連貫就可以了,這種情況使用UDP更合理。
    2、 開發(fā)Datagram程序流程
    MIDP的Datagram點到點程序和開發(fā)Socket點到點的程序流程相似,都是C/S的交流方式。
    Datagram程序繼承于DataInput和DataOutput類,Sun公司開發(fā)這類的目的是為了提供一個簡單的途徑讀取和發(fā)送二進(jìn)制數(shù)據(jù),替代使用getData()和sendData()方法。
    使用Datagram的read/write方法的時候,讀取數(shù)據(jù)的指針會自動增加。與Socket程序的讀取數(shù)據(jù)不同的是Datagram程序每次寫入一個數(shù)據(jù)報之前,都要用reset()方法復(fù)位,例如下面的代碼寫入了數(shù)據(jù)包信息:
    DatagramConnection connection;
    datagram = connection.new Datagram(max);
    //重設(shè)并準(zhǔn)備重新獲得數(shù)據(jù)
    datagram.reset();
    //writeUTF會自動增加數(shù)據(jù)報的長度
    datagram.writeUTF(“hello the world!”);
    connection.send(datagram);
    下面的代碼讀取一個單個的數(shù)據(jù)報信息:
    datagram = connection.new Datagram(max);
    connection.receive(datagram);
    message = datagram.readUTF();
    服務(wù)器端監(jiān)聽的地址編寫格式是”datagram://:8859”。

    posted on 2008-09-01 19:51 騎豬闖天下 閱讀(920) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 永久免费毛片在线播放| 大地影院MV在线观看视频免费| 精品亚洲国产成AV人片传媒| 亚洲av无码无在线观看红杏| 亚洲一区影音先锋色资源| 国产免费一区二区三区在线观看| 免费99精品国产自在现线| 免费国产小视频在线观看| 亚洲国产精品国自产拍AV| 亚洲性线免费观看视频成熟| 爱情岛论坛亚洲品质自拍视频网站| 美女被免费网站在线视频免费 | aa在线免费观看| 99久久精品免费视频| 成人啪精品视频免费网站| 亚洲乱码日产精品a级毛片久久| 久久精品国产精品亚洲蜜月| 中文字幕成人免费视频| 亚洲AV网站在线观看| 在线播放亚洲第一字幕| 国内精品久久久久影院亚洲| 香蕉免费一区二区三区| 亚洲精品久久久www| 国产在线播放线91免费| 亚洲福利精品电影在线观看| 一区二区三区免费视频播放器| 最新猫咪www免费人成| 男人的天堂av亚洲一区2区| 久久国产免费福利永久| 国产亚洲精品精华液| 牛牛在线精品观看免费正 | 妞干网免费视频在线观看| 亚洲视频免费在线看| 日本免费一区二区三区| 亚洲午夜福利在线视频| 中文字幕亚洲免费无线观看日本| 亚洲区视频在线观看| 成年人视频免费在线观看| 久久亚洲sm情趣捆绑调教| 四虎成人免费影院网址| 免费a级毛片无码a∨免费软件|