java android面試題分析總結《三

3.2基於UDP協議的數據傳輸 
服務器端首先創建一個DatagramSocket對象,並且指點監聽的端 口。接下來創建一個空的DatagramSocket對象用於接收數據 (bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)), 

使用DatagramSocket的receive方法接收客戶端發送的數據,receive()與serversocket的accepet()類似, 在沒有數據進行接收的處於堵塞狀態。
客戶端也創建個DatagramSocket對象,並且指點監聽的端口。接 下來創建一個InetAddress對象,這個對象類似與一個網絡的發送地址 

(InetAddressserveraddress=InetAddress.getByName("172.168.1.120"))

.定義要發送的 一個字符串,創建一個DatagramPacket對象,並制定要講這個數據報包發送到網絡的那個地址以及端口號,

最後使用DatagramSocket 的對象的send()發送數據。

*(Stringstr="hello";bytedata[]=str.getByte(); DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)

四、android 實現socket簡單通信

4.1使用TCP協議通信

android端實現:

[java] view plaincopy 

  1.     protected void connectServerWithTCPSocket() {  
  2.   
  3.         Socket socket;  
  4.         try {// 創建一個Socket對象,並指定服務端的IP及端口號  
  5.             socket = new Socket("192.168.1.32", 1989);  
  6.             // 創建一個InputStream用戶讀取要發送的文件。  
  7.             InputStream inputStream = new FileInputStream("e://a.txt");  
  8.             // 獲取Socket的OutputStream對象用於發送數據。  
  9.             OutputStream outputStream = socket.getOutputStream();  
  10.             // 創建一個byte類型的buffer字節數組,用於存放讀取的本地文件  
  11.             byte buffer[] = new byte[4 * 1024];  
  12.             int temp = 0;  
  13.             // 循環讀取文件  
  14.             while ((temp = inputStream.read(buffer)) != -1) {  
  15.                 // 把數據寫入到OuputStream對象中  
  16.                 outputStream.write(buffer, 0, temp);  
  17.             }  
  18.             // 發送讀取的數據到服務端  
  19.             outputStream.flush();  
  20.   
  21.             /** 或創建一個報文,使用BufferedWriter寫入,看你的需求 **/  
  22. //          String socketData = "[2143213;21343fjks;213]";  
  23. //          BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(  
  24. //                  socket.getOutputStream()));  
  25. //          writer.write(socketData.replace("\n", " ") + "\n");  
  26. //          writer.flush();  
  27.             /************************************************/  
  28.         } catch (UnknownHostException e) {  
  29.             e.printStackTrace();  
  30.         } catch (IOException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.   
  34.     }  


服務器端簡單實現: 

[java] view plaincopy 

  1. public void ServerReceviedByTcp() {  
  2.     // 聲明一個ServerSocket對象  
  3.     ServerSocket serverSocket = null;  
  4.     try {  
  5.         // 創建一個ServerSocket對象,並讓這個Socket在1989端口監聽  
  6.         serverSocket = new ServerSocket(1989);  
  7.         // 調用ServerSocket的accept()方法,接受客戶端所發送的請求,  
  8.         // 如果客戶端沒有發送數據,那麼該線程就停滯不繼續  
  9.         Socket socket = serverSocket.accept();  
  10.         // 從Socket當中得到InputStream對象  
  11.         InputStream inputStream = socket.getInputStream();  
  12.         byte buffer[] = new byte[1024 * 4];  
  13.         int temp = 0;  
  14.         // 從InputStream當中讀取客戶端所發送的數據  
  15.         while ((temp = inputStream.read(buffer)) != -1) {  
  16.             System.out.println(new String(buffer, 0, temp));  
  17.         }  
  18.         serverSocket.close();  
  19.     } catch (IOException e) {  
  20.         e.printStackTrace();  
  21.     }  
  22. }  


4.2使用UDP協議通信 

客戶端發送數據實現:

[java] view plaincopy 

  1. protected void connectServerWithUDPSocket() {  
  2.       
  3.     DatagramSocket socket;  
  4.     try {  
  5.         //創建DatagramSocket對象並指定一個端口號,注意,如果客戶端需要接收服務器的返回數據,  
  6.         //還需要使用這個端口號來receive,所以一定要記住  
  7.         socket = new DatagramSocket(1985);  
  8.         //使用InetAddress(Inet4Address).getByName把IP地址轉換爲網絡地址    
  9.         InetAddress serverAddress = InetAddress.getByName("192.168.1.32");  
  10.         //Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName("192.168.1.32");    
  11.         String str = "[2143213;21343fjks;213]";//設置要發送的報文    
  12.         byte data[] = str.getBytes();//把字符串str字符串轉換爲字節數組    
  13.         //創建一個DatagramPacket對象,用於發送數據。    
  14.         //參數一:要發送的數據  參數二:數據的長度  參數三:服務端的網絡地址  參數四:服務器端端口號   
  15.         DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);    
  16.         socket.send(packet);//把數據發送到服務端。    
  17.     } catch (SocketException e) {  
  18.         e.printStackTrace();  
  19.     } catch (UnknownHostException e) {  
  20.         e.printStackTrace();  
  21.     } catch (IOException e) {  
  22.         e.printStackTrace();  
  23.     }    
  24. }  


客戶端接收服務器返回的數據: 

[java] view plaincopy 

  1. public void ReceiveServerSocketData() {  
  2.     DatagramSocket socket;  
  3.     try {  
  4.         //實例化的端口號要和發送時的socket一致,否則收不到data  
  5.         socket = new DatagramSocket(1985);  
  6.         byte data[] = new byte[4 * 1024];  
  7.         //參數一:要接受的data 參數二:data的長度  
  8.         DatagramPacket packet = new DatagramPacket(data, data.length);  
  9.         socket.receive(packet);  
  10.         //把接收到的data轉換爲String字符串  
  11.         String result = new String(packet.getData(), packet.getOffset(),  
  12.                 packet.getLength());  
  13.         socket.close();//不使用了記得要關閉  
  14.         System.out.println("the number of reveived Socket is  :" + flag  
  15.                 + "udpData:" + result);  
  16.     } catch (SocketException e) {  
  17.         e.printStackTrace();  
  18.     } catch (IOException e) {  
  19.         e.printStackTrace();  
  20.     }  
  21. }  


服務器接收客戶端實現: 

[java] view plaincopy 

  1. public void ServerReceviedByUdp(){  
  2.     //創建一個DatagramSocket對象,並指定監聽端口。(UDP使用DatagramSocket)    
  3.     DatagramSocket socket;  
  4.     try {  
  5.         socket = new DatagramSocket(10025);  
  6.         //創建一個byte類型的數組,用於存放接收到得數據    
  7.         byte data[] = new byte[4*1024];    
  8.         //創建一個DatagramPacket對象,並指定DatagramPacket對象的大小    
  9.         DatagramPacket packet = new DatagramPacket(data,data.length);    
  10.         //讀取接收到得數據    
  11.         socket.receive(packet);    
  12.         //把客戶端發送的數據轉換爲字符串。    
  13.         //使用三個參數的String方法。參數一:數據包 參數二:起始位置 參數三:數據包長    
  14.         String result = new String(packet.getData(),packet.getOffset() ,packet.getLength());    
  15.     } catch (SocketException e) {  
  16.         e.printStackTrace();  
  17.     } catch (IOException e) {  
  18.         e.printStackTrace();  
  19.     }    
  20. }  

 

五、總結:

使用UDP方式android端和服務器端接收可以看出,其實android端和服務器端的發送和接收大庭相徑,只要端口號正確了,相互通信就沒有問題,TCP使用的是流的方式發送,UDP是以包的形式發送。

 

Android操作HTTP實現與服務器通信

本示例以Servlet爲例,演示Android與Servlet的通信。

衆所周知,Android與服務器通信通常採用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post兩種方式。至於Socket通信會在以後的博文中介紹。

 

HTTP協議簡介: 

HTTP (Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網常用的協議之一,HTTP協議是建立在TCP協議之上的一種協議。

HTTP連接最顯 著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束後,會主動釋放連接。從建立連接到關閉連接的過程稱爲“一次連接”。  在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求後,就自動釋放連接。  在HTTP 1.1中則可以在一次連接中處理多個請求,並且多個請求可以重疊進行,不需要等待一個請求結束後再發送下一個請求。

 

由 於HTTP在每次請求結束後都會主動釋放連接,因此HTTP連接是一種“短連接”、“無狀態”,要保持客戶端程序的在線狀態,需要不斷地向服務器發起連接 請求。通常的做法是即使不需要獲得任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次“保持連接”的請求,服務器在收到該請求後對客戶端進行回 復,表明知道客戶端“在線”。若服務器長時間無法收到客戶端的請求,則認爲客戶端“下線”,若客戶端長時間無法收到服務器的回覆,則認爲網絡已經斷開。 

基於HTTP1.0協議的客戶端在每次向服務器發出請求後,服務器就會向客戶端返回響應消息,在確認客戶端已經收到響應消息後,服務端就會關閉網絡連接。在這個數據傳輸過程中,並不保存任何歷史信息和狀態信息,因此,HTTP協議也被認爲是無狀態的協議。

  HTTP1.1 和HTTP1.0相比較而言,最大的區別就是增加了持久連接支持。當客戶端使用HTTP1.1協議連接到服務器後,服務器就將關閉客戶端連接的主動權交還 給客戶端;也就是說,只要不調用Socket類的close方法關閉網絡連接,就可以繼續向服務器發送HTTP請求。

 

HTTP連接使用的是“請求—響應”的方式(2次握手),不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求後,服務器端才能回覆數據。而Socket連接在雙方建立起連接後就可以直接進行數據的傳輸

 

  HTTP協議的特點:

  支持B/S及C/S模式; 

簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。 

靈活:HTTP 允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type 加以標記; 

無狀態:HTTP 協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。

 

HTTP協議請求方法: 

請求行中包括了請求方法,解釋如下: 

GET 請求獲取Request-URI 所標識的資源; 

POST 在Request-URI 所標識的資源後附加新的數據; 

HEAD 請求獲取由Request-URI 所標識的資源的響應消息報頭 

PUT 請求服務器存儲一個資源,並用Request-URI 作爲其標識 

DELETE 請求服務器刪除Request-URI 所標識的資源; 

TRACE 請求服務器回送收到的請求信息,主要用於測試或診斷 

CONNECT 保留將來使用 

OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

Get與Post請求區別: 

Post 請求可以向服務器傳送數據,而且數據放在HTML HEADER內一起傳送到服務端URL地址,數據對用戶不可見。而get是把參數數據隊列加到提交的URL中,值和表單內各個字段一一對應, 例如(http://www.baidu.com/s?w=%C4&inputT=2710)

get 傳送的數據量較小,不能大於2KB。post傳送的數據量較大,一般被默認爲不受限制。但理論上,IIS4中最大量爲80KB,IIS5中爲100KB。 

get安全性非常低,post安全性較高。

 

在Android開發中我們經常會用到網絡連接功能與服務器進行數據的交互,爲此Android的SDK提供了Apache的HttpClient來方便我們使用各種Http服務

///

Get()  先創建一個HttpClient 然後再創建一個HttpGet,通過HttpClient的execute方法來發送一個HttpGet並且返回String內容。

 

try {
        // 創建一個默認的HttpClient
        HttpClient httpclient =new DefaultHttpClient();
        // 創建一個GET請求
        HttpGet request =new HttpGet("www.google.com");
        // 發送GET請求,並將響應內容轉換成字符串
        String response = httpclient.execute(request, new BasicResponseHandler());
        Log.v("response text", response);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

///////////////////////////////

Post()

 publicstatic String post(String url, NameValuePair... params) {
        try {
            // 編碼參數
            List<NameValuePair> formparams =new ArrayList<NameValuePair>(); // 請求參數
for (NameValuePair p : params) {
                formparams.add(p);
            }
            UrlEncodedFormEntity entity =new UrlEncodedFormEntity(formparams,
                    CHARSET);
            // 創建POST請求
            HttpPost request =new HttpPost(url);
            request.setEntity(entity);
            // 發送請求
            HttpClient client = getHttpClient();
            HttpResponse response = client.execute(request);
            if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                thrownew RuntimeException("請求失敗");
            }
            HttpEntity resEntity =  response.getEntity();
            return (resEntity ==null) ?null : EntityUtils.toString(resEntity, CHARSET);
        } catch (UnsupportedEncodingException e) {
            Log.w(TAG, e.getMessage());
            returnnull;
        } catch (ClientProtocolException e) {
            Log.w(TAG, e.getMessage());
            returnnull;
        } catch (IOException e) {
            thrownew RuntimeException("連接失敗", e);
        }

    } 

發佈了144 篇原創文章 · 獲贊 18 · 訪問量 74萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章