Android網絡通信方式

      轉載自http://www.apkbus.com/android-13316-1-1.html

     手機作爲一種通訊終端(MMS),伴隨着網絡的升級而不斷的升級換代。1995年1G問世,手機只能進行基本的語音通訊,1996-1997年2G(GSM,CDMA)及其後的GPRS,EDGE等技術的快速發展,手機開始逐漸增加了數據服務功能。2009年開始,3G在全世界開始大規模佈置以及蘋果創造性開發新型蘋果手機。手機慢慢的變成互聯網的終端,從而帶動了一個新的時代--移動互聯網時代。因此現代手機通常都支持這些常用網絡設備,如WIFI,NFC,藍牙等。

Android是由互聯網巨頭Google帶頭開發的,因此對網絡功能的支持是必不可少的。Google的應用層採用的是Java語言。所以JAVA支持的網絡編程方式Android都支持,同時Google還引入了Apache 的HTTP擴展包。另外,針對WIFI,NFC,分別提供的單獨的開發API.

表1展示了Android SDK中的一些與網絡有關的API包名
表1. Android SDK 網絡包
包                      描述                                                               API Level
Java.net                        提供與聯網有關的類,包括流和數據包(datagram)sockets、Internet 協議和常見 HTTP 處理。該包是一個多功能網絡資源。有經驗的 Java 開發人員可以立即使用這個熟悉的包創建應用程序。        1
java.io                        雖然沒有提供顯式的聯網功能,但是仍然非常重要。該包中的類由其他 Java 包中提供的 socket 和連接使用。它們還用於與本地文件(在與網絡進行交互時會經常出現)的交互        1
java.nio                        包含表示特定數據類型的緩衝區的類。適合用於兩個基於 Java 語言的端點之間的通信。        1
org.apache.*        表示許多爲 HTTP 通信提供精確控制和功能的包。可以將 Apache 視爲流行的開源 Web 服務器。        1
android.net        除核心 java.net.* 類以外,包含額外的網絡訪問 socket。該包包括 URI 類,後者頻繁用於 Android 應用程序開發,而不僅僅是傳統的聯網方面。        1
android.net.http        包含處理 SSL 證書的類。        1
android.net.wifi        包含在 Android 平臺上管理有關 WiFi(802.11 無線 Ethernet)所有方面的類。        1
android.telephony.gsm        包含用於管理和發送 SMS(文本)消息的類。一段時間後,可能會引入額外的包來來爲非 GSM 網絡提供類似的功能,比如 CDMA 或 android.telephony.cdma 等網絡。        1
Android.net.sip        包含Andriod平臺上管理有關SIP協議如建立和迴應Voip的類        9
Android.nfc        包含所有用來管理近場通信相關的功能類        9

在Android中幾種網絡編程的方式:
(1)針對TCP/IP的Socket、ServerSocket
(2)針對UDP的DatagramSocket、DatagramPackage。這裏需要注意的是,考慮到Android設備通常是手持終端,IP都是隨着上網進行分配的。不是固定的。因此開發也是有一點與普通互聯網應用有所差異的。
(3)針對直接URL的HttpURLConnection
(4)Google集成了Apache HTTP客戶端,可使用HTTP進行網絡編程。針對HTTP,Google集成了Appache Http core和httpclient 4版本,因此特別注意Android不支持httpclient 3.x系列,而且目前並不支持Multipart(MIME),需要自行添加httpmime.jar 
(5)使用Web Service。Android可以通過開源包如jackson去支持Xmlrpc和Jsonrpc,另外也可以用Ksoap2去實現Webservice 
  (6) 直接使用WebView視圖組件顯示網頁。基於WebView 進行開發,Google已經提供了一個基於chrome-lite的Web瀏覽器,直接就可以進行上網瀏覽網頁。

一、我們先來看第一種,針對TCP/IP Socket、ServerSocket的形式。
TCP/IP是一種協議,是一種面向連接的、可靠的協議。Socket僅僅是對TCP、UDP網絡接口的封裝,不涉及上層協議。TCP、UDP傳輸特性不同,分別適用於不同類型的應用層協議,其中TCP有連接,延時較長,能保證服務質量;UDP無連接,需要應用程序進行數據分包、延時短,效率高,數據包可能丟失或到達對端發生順序混亂。在Socket之上可以實現這些RFC標準的應用層協議,也可以自定義實現私有的應用層協議。

在JAVA編程中, 經常使用java.net和javax.net包來開發socket程序,下面列出所有常用的類,並簡單介紹。關於詳細的信息請參看JAVA文檔。

Java.net
Java.net.Socket                        客戶端連接使用的TCP socket
Java.net.DatagramSocket        客戶端和服務端共同使用的UDP socket
Java.net.ServerSocket        服務端TCP socket監聽端口
Java.netInetAddress                        IP地址封裝類
Java.net.DataGramPacket        通過DatagramSocket收發的數據包的封裝類,包括數據和對端的IP地址、UDP端口

Javax.net
Javax.net.SocketFactory                        客戶端連接使用的T CP socket
Javax.net.ServerSocketFactory        服務端TCP socket監聽端口
Javax.net.ssl.SSLSocketFactory        SSL客戶端Socket構造器
Javax.net.ssl.SSLServerFactory        SSL服務端監聽Socket構造器

示例代碼: android+socket編程實例.rar

二、針對UDP的DatagramSocket、DatagramPackage
1.對於UDP服務端,首先啓動偵聽服務,然後得到數據包進行處理,組後根據獲得數據包進行反饋。
2.UDP socket沒有連接的概念,因此構造完成的DatagramSocket不會發出向對端的網絡連接請求,在每一個發送的UDP數據包中包含目的地址和端口。因爲UDP數據不會在對端進行重新組包,因此一次發送的數據長度必須加以限制。Socket.send(outputPacket);用於發送一個數據包;socket.receive(inputPacket);用於接收一個數據包。
 

    

示例代碼:
服務器端:
public class UDPServer{
             public static void main(String[] args) throws Exception{
                     DatagramSocket udpSocket = new DatagramSocket(8000);
                     while(true){
                             try{
                                     // UDP數據讀取
                                     DatagramPacket packet = new DatagramPacket(new byte[512],512);
                                     udpSocket.receive(packet);
                                     String msg = new String(packet.getData()), 0,packet.getLength());
                                     System.out.println(msg);
                                     if(msg.equals("exit")){
                                             break;
                                     }
                                     
                                     // UDP數據發送
                                     SimpleDateFormat f = new SimpleDateFormat("MMM dd,yyyy kk:mm:ss");
                                     String time = "現在的時間是:" + f.format(new Date());
                                     packet.setData(time.getBytes());
                                     udpSocket.send(packet);
                                     
                             }catch(Exception e){
                                     e.printStackTrace();
                             }
                     }
                     udpSocket.close();
             }
     }

客戶端:
public void client(){
             InetAddress remoteIP;
                try {
                        remoteIP = InetAddress.getByName("localhost");
                        DatagramSocket socket = new DatagramSocket();
                } catch (UnknownHostException e1) { 
                        e1.printStackTrace();
                }
             
             BufferedReader wt = new BufferedReader (new InputStreamReader(System.in));
             System.out.println("input one line ,user \"exit\" to quit the server "); 
             while(true){
                     try{
                             // 讀取輸入
                             String str = wt.readLine();
                             byte[] outputData = str.getBytes();
                             // UDP socket 數據發送
                             DatagramPacket outputPacket = new DatagramPacket(outputData,outputData.length,remoteIP,8000);
                             socket.send(outputPacket);
                             if(str.equals("exit")){
                                     //udp 數據讀取
                                     DatagramPacket inputPacket = new DatagramPacket(new byte[512],512);
                                     socket.receive(inputPacket);
                                     System.out.println(new String(inputPacket.getData(),0,inputPacket.getLength()));
                                      
                             }
                     }catch(Exception e){
                             e.printStackTrace();
                     }
             }
             socket.close();
     }

三、針對直接URL的HttpURLConnection
這個就是把請求的方式從HttpClient換成HttpURLConnection就可以了。沒什麼可以說的,自己看看吧。

示例代碼:無

四、Google集成了Apache HTTP客戶端,可使用HTTP進行網絡編程
這個不多說了,網絡編程,必須會的。自己看代碼吧。服務端我使用三種方式:S2SH、只用Struts2、Servlet。客戶端就一種,只不過換個請求的URL。服務端和客戶端交互使用了兩種方式:XML、JSON,目前開放平臺返回的數據都是支持這兩種數據格式的。所以我也實現了這兩種數據格式。其實還有一種格式,就是google的protocal buffer,這種形式在國內用的人比較少,我也沒弄,感興趣的同學看我提供的文檔,自己研究吧。注意把裏面的IP換成自己電腦的IP地址。

示例代碼:
服務端:ServletTest1.rar、StrAnd.rar、WebAndroid.rar
客戶端:WebAndroidClient.rar

參考網址:
http://www.cnblogs.com/zhangdong ... /04/19/2020688.html
http://blog.csdn.net/woshisap/article/details/6621571
http://www.360doc.com/content/11/0521/01/4154133_118259561.shtml

注意:在只使用Struts2的服務器端,可以這麼配置:
<package name="struts-main" extends="json-default" >   
      <action name="*UserAction" class="userAction" method="{1}">
         <result type="json"></result>
      </action>
  </package>
也可以這麼配置:
<package name="struts-main" extends="struts-default" >   
      <action name="*UserAction" class="userAction" method="{1}">
          <result name="register">/WEB-INF/page/register.jsp</result>
          <result name="save">/WEB-INF/page/index.jsp</result>        
      </action>
  </package>

       但是其實返回數據的時候都是封裝JSON字符串,沒用到第一種形式的配置的功能。據說,用第一種配置方式,struts2可以自動把返回的數據封裝成JSON字符串的形式,但是我沒測試成功。。。。我返現返回什麼格式還是什麼格式,並沒有把數據自動封裝成JSON返回。
    在使用S2SH的服務端,就不能用第一種方式配置。只能用第二種方式,然後服務端封裝JSON返回客戶端。如果用第一種方式配置,就會發生404錯誤。無法找到服務器端。
    在使用Servlet的服務端,可以通過下面這種方式設置返回類型,但是其實沒用,你設置了,它也不返回。你只能自己封裝XML文件或者JSON字符串,然後返回。
response.setContentType("application/json;charset=utf-8");

(5)使用Web Service
我之前只聽說過什麼事webservice,因此主要是參考下面文章實現的DEMO,他給出了一些實例代碼,不全,我給基本補全了。顯示天氣信息我都在LOG輸出了,沒有顯示在界面上,如果大家覺得不爽,可以把信息直接顯示在界面上就可以了。因爲我被這個問題困擾了2天,弄的很崩潰,所以就沒繼續弄。大家自己看吧。
那麼什麼是webService呢?,它是一種基於SAOP協議的遠程調用標準,通過webservice可以將不同操作系統平臺,不同語言,不同技術整合到一起。在Android中,第三方公司提供了基於webservice的jar包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
http://www.cnblogs.com/zhangdong ... /04/19/2020688.html
http://www.cnblogs.com/ghj1976/archive/2011/04/26/2028904.html
示例代碼:SoapAndroidTeset.rar、sserEx09.rar

(6) 直接使用WebView視圖組件顯示網頁
這就是使用webview顯示網頁的問題,比較容易,大家自己看吧。我就不貼實例代碼了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章