程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 網絡連接

網絡連接

編輯:J2ME
J2ME提供了HttpConnection和SocketConnection。前者從API級提供了對http協議的支持,而後者只是單純的一個socket流API。

    實際上對於使用Http協議的上層應用來說,網絡層使用Http或者Socke應該是透明的。作為框架,應該為用戶提供方便的選擇方式。
    J2ME中對HTTP 1.2中定義的KEEPALIVE支持得並不是很好,並不能獲得一個http的長連接。對於JSE中http connection的實現還沒驗證。
    使用Socket的一個好處是可以避免為每個網絡請求建立單獨的Connection。並且因為socket的inputStream, outputStream是雙工的方式工作,所以可以連續的發送網絡請求而不必等待網絡回應。
    如果讓socket的inputStream/outputStream以雙工的方式工作(即:通過outputStream發送之後不等待 inputStream的response),那麼需要應用層的協議進行支持。比如,需要對發出的網絡請求進行編號,這樣從inputstream中獲得 response的時候可以把這個回應匹配到正確的請求上。實現雙工,很直接的想法是inputStream、outputStream分別由單獨的一個線程處理。

    這個工具包應該能夠做到支持:
  1. Http GET/POST;
  2. File download;
  3. 可以選擇使用socket或是Http;
  4. 支持同步/異步(阻塞/非阻塞)發送請求,提供timeout機制;
  5. 清晰的異常定義,方便上層進行錯誤處理。
  6. 對於socket是否可用連接池?[對於J2ME程序似乎沒有必要]
    Connection中的receive, send都是阻塞的。如果要實現異步收發,需要在一個單獨的線程中處理請求。

    以下是通過把阻塞的API放在一個線程中運行而獲得的異步效果。理想狀態下,在到達了Timeout事件後,應該把這個線程關閉。但是因為這個線程中存在阻塞方法,所以不能及時地獲得停止通知(很難終止這個線程)。這個網絡請求很可能會在你設置的timeout時間後獲得網絡response。為了處理 timeout之後仍舊獲得網絡數據的情況,可以先把異步請求的數據對象放到一個隊列中,如果網絡回應在timeout之前返回,則從這個隊列中查找該對象並移走這個對象;  當timeout之後,也應該把這個對象移走(可考慮放到另一個隊列進行其它的特殊處理),這樣當延遲的網絡回應到來後,從隊列中找不到對象,就不做處理。
       
    sendRequestSynch是同步的API。 sendRequest()會調用同步方法,因此放在一個單獨的線程中運行。匿名線程t啟動之後,通過request.wait()方法,使調用 sendRequestSynch()的方法被阻塞。從request.wait()方法恢復之後,判斷是否timeout發生。
    public void sendRequestSynch(final NetworkRequest request, long timeout) throws Exception {
        synchronized (request) {
             Thread t = new Thread() {
                 public void run() {
                     try {
                         log.debug("send request in another thread.");
                         sendRequest(request);
                     }catch (Exception e) {
                         log.warn(e.getMessage());
                    }
                    log.debug("Exit the thread.");
                 }
             };
             t.start();   
             
             log.debug("Try to wait for " + timeout);
             request.wait(timeout);
             if (request.isDelayed()) {
                 queue.removeElement(request);
                 timeoutQueue.addElement(request);
                 log.debug("Request TIMEOUT !!!!!!!!!!!!!!!!");
                 log.debug("Stop the network request thread for the timeout.");
             }else {
                 log.debug("Be NotifIEd and wakeup.");
             }
        }
    }
    sendRequestAsynch是異步的API。這個是寫作過程中的一個版本。在revIEw之後發現其中存在同步問題。synchronized (request)不是在啟動孫子線程tt之後執行。問題在於如果sendRequest(request)在執行到最後是發送request.notifyAll()時,可能還沒有執行synchronized (request) 這樣就存在request.wait(timeout)不會被喚醒而超時的問題。
    public void sendRequestAsynch(final NetworkRequest request, final long timeout) throws Exception {
         Thread t = new Thread() {             public void run() {
                 try {
                     log.debug("send request in another thread.");
                     
                     Thread tt = new Thread() {
                         public void run() {
                             try {
                                 log.debug("send request in grandson thread. " + request.getSequenceId());
                                 sendRequest(request);
                             }catch (Exception e) {
                                 log.warn(e.getMessage());
                             }
                         }
                     };
                     tt.start();
                     
                     synchronized (request) {
                         log.debug("Try to wait for " + timeout + "  " + request.getSequenceId());
                         request.wait(timeout);
                         if (request.isDelayed()) {
                             queue.removeElement(request);
                             timeoutQueue.addElement(request);
                             log.debug("Request TIMEOUT !!!!!!!!!!!!!!!!");
                             log.debug("Stop the network request thread for the timeout.");
                         }else {
                             log.debug("Be NotifIEd and wakeup.");
                         }
                     }
                 }catch (Exception e) {
                     log.warn(e.getMessage());
                }
                log.debug("Exit the thread.");
             }
         };
         t.start();   
    }
     應當把sendRequest(request) 放到同步塊中。改正後的代碼:
    public void sendRequestAsynch(final NetworkRequest request, final long timeout) throws Exception {
         Thread t = new Thread() {
             public void run() {
                 try {
                     log.debug("send request in another thread.");
                     synchronized (request) {
                         Thread tt = new Thread() {
                             public void run() {
                                 try {
                                     log.debug("send request in grandson thread. " + request.getSequenceId());
                                     sendRequest(request);
                                 }catch (Exception e) {
                                     log.warn(e.getMessage());
                                 }
                             }
                         };
                         tt.start();
                     
                         log.debug("Try to wait for " + timeout + "  " + request.getSequenceId());
                         request.wait(timeout);
                         if (request.isDelayed()) {
                             queue.removeElement(request);
                             timeoutQueue.addElement(request);
                             log.debug("Request TIMEOUT !!!!!!!!!!!!!!!!");
                             log.debug("Stop the network request thread for the timeout.");
                         }else {
                             log.debug("Be NotifIEd and wakeup.");
                         }
                     }
                 }catch (Exception e) {
                     log.warn(e.getMessage());
                }
                log.debug("Exit the thread.");
             }
         };
         t.start();   
    }
exception的處理還沒有規范起來。許多細節還待完善(post還沒有被支持),...

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved