1. 程式人生 > >_052_Android_Android網路程式設計總結

_052_Android_Android網路程式設計總結

1.httpURLConnection協議使用

1)建立一個URL物件

2)利用HttpURLConnection物件從網路中獲取網頁資料,設定請求方法

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("POST");// 設定請求方法為post

3)設定連線超時

conn.setConnectTimeout(6*1000);

4)對響應碼進行判斷

if (conn.getResponseCode() != 200)    //從Internet獲取網頁,傳送請求,將網頁以流的形式讀回來

throw new RuntimeException("請求url失敗");

5)處理輸入輸出流

InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //檔案流輸入出文件用outStream.write
7)conn.disconnect();

public class NetUtils {
        public static String post(String url, String content) {
            HttpURLConnection conn = null;
            try {
                // 建立一個URL物件
                URL mURL = new URL(url);
                // 呼叫URL的openConnection()方法,獲取HttpURLConnection物件
                conn = (HttpURLConnection) mURL.openConnection();
 
                conn.setRequestMethod("POST");// 設定請求方法為post
                conn.setReadTimeout(5000);// 設定讀取超時為5秒
                conn.setConnectTimeout(10000);// 設定連線網路超時為10秒
                conn.setDoOutput(true);// 設定此方法,允許向伺服器輸出內容
 
                // post請求的引數
                String data = content;
                // 獲得一個輸出流,向伺服器寫資料,預設情況下,系統不允許向伺服器輸出內容
                OutputStream out = conn.getOutputStream();// 獲得一個輸出流,向伺服器寫資料
                out.write(data.getBytes());
                out.flush();
                out.close();
 
                int responseCode = conn.getResponseCode();// 呼叫此方法就不必再使用conn.connect()方法
                if (responseCode == 200) {
 
                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }
 
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    conn.disconnect();// 關閉連線
                }
            }
 
            return null;
        }
 
        public static String get(String url) {
            HttpURLConnection conn = null;
            try {
                // 利用string url構建URL物件
                URL mURL = new URL(url);
                conn = (HttpURLConnection) mURL.openConnection();
 
                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(10000);
 
                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {
 
                    InputStream is = conn.getInputStream();
                    String response = getStringFromInputStream(is);
                    return response;
                } else {
                    throw new NetworkErrorException("response status is "+responseCode);
                }
 
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
 
                if (conn != null) {
                    conn.disconnect();
                }
            }
 
            return null;
        }
 
        private static String getStringFromInputStream(InputStream is)
                throws IOException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            // 模板程式碼 必須熟練
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            is.close();
            String state = os.toString();// 把流中的資料轉換成字串,採用的編碼是utf-8(模擬器預設編碼)
            os.close();
            return state;
        }
    }

2.httpClient的使用

1. 建立HttpClient物件。

2. 建立請求方法的例項,並指定請求URL。如果需要傳送GET請求,建立HttpGet物件;如果需要傳送POST請求,建立HttpPost物件。

3. 如果需要傳送請求引數,可呼叫HttpGet、HttpPost共同的setParams(HetpParams params)方法來新增請求引數;對於HttpPost物件而言,也可呼叫setEntity(HttpEntity entity)方法來設定請求引數。

4. 呼叫HttpClient物件的execute(HttpUriRequest request)傳送請求,該方法返回一個HttpResponse。

5. 呼叫HttpResponse的getAllHeaders()、getHeaders(String name)等方法可獲取伺服器的響應頭;呼叫HttpResponse的getEntity()方法可獲取HttpEntity物件,該物件包裝了伺服器的響應內容。程式可通過該物件獲取伺服器的響應內容。

6. 釋放連線。無論執行方法是否成功,都必須釋放連線

import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.UnsupportedEncodingException;  
import java.security.KeyManagementException;  
import java.security.KeyStore;  
import java.security.KeyStoreException;  
import java.security.NoSuchAlgorithmException;  
import java.security.cert.CertificateException;  
import java.util.ArrayList;  
import java.util.List;  
  
import javax.net.ssl.SSLContext;  
  
import org.apache.http.HttpEntity;  
import org.apache.http.NameValuePair;  
import org.apache.http.ParseException;  
import org.apache.http.client.ClientProtocolException;  
import org.apache.http.client.entity.UrlEncodedFormEntity;  
import org.apache.http.client.methods.CloseableHttpResponse;  
import org.apache.http.client.methods.HttpGet;  
import org.apache.http.client.methods.HttpPost;  
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
import org.apache.http.conn.ssl.SSLContexts;  
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;  
import org.apache.http.entity.ContentType;  
import org.apache.http.entity.mime.MultipartEntityBuilder;  
import org.apache.http.entity.mime.content.FileBody;  
import org.apache.http.entity.mime.content.StringBody;  
import org.apache.http.impl.client.CloseableHttpClient;  
import org.apache.http.impl.client.HttpClients;  
import org.apache.http.message.BasicNameValuePair;  
import org.apache.http.util.EntityUtils;  
import org.junit.Test;  
  
public class HttpClientTest {  
  
    @Test  
    public void jUnitTest() {  
        get();  
    }  
  
    /** 
     * HttpClient連線SSL 
     */  
    public void ssl() {  
        CloseableHttpClient httpclient = null;  
        try {  
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());  
            FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore"));  
            try {  
                // 載入keyStore d:\\tomcat.keystore    
                trustStore.load(instream, "123456".toCharArray());  
            } catch (CertificateException e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                    instream.close();  
                } catch (Exception ignore) {  
                }  
            }  
            // 相信自己的CA和所有自簽名的證書  
            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();  
            // 只允許使用TLSv1協議  
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,  
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();  
            // 建立http請求(get方式)  
            HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action");  
            System.out.println("executing request" + httpget.getRequestLine());  
            CloseableHttpResponse response = httpclient.execute(httpget);  
            try {  
                HttpEntity entity = response.getEntity();  
                System.out.println("----------------------------------------");  
                System.out.println(response.getStatusLine());  
                if (entity != null) {  
                    System.out.println("Response content length: " + entity.getContentLength());  
                    System.out.println(EntityUtils.toString(entity));  
                    EntityUtils.consume(entity);  
                }  
            } finally {  
                response.close();  
            }  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (KeyManagementException e) {  
            e.printStackTrace();  
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        } catch (KeyStoreException e) {  
            e.printStackTrace();  
        } finally {  
            if (httpclient != null) {  
                try {  
                    httpclient.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
  
    /** 
     * post方式提交表單(模擬使用者登入請求) 
     */  
    public void postForm() {  
        // 建立預設的httpClient例項.    
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        // 建立httppost    
        HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");  
        // 建立引數佇列    
        List<namevaluepair> formparams = new ArrayList<namevaluepair>();  
        formparams.add(new BasicNameValuePair("username", "admin"));  
        formparams.add(new BasicNameValuePair("password", "123456"));  
        UrlEncodedFormEntity uefEntity;  
        try {  
            uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");  
            httppost.setEntity(uefEntity);  
            System.out.println("executing request " + httppost.getURI());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                HttpEntity entity = response.getEntity();  
                if (entity != null) {  
                    System.out.println("--------------------------------------");  
                    System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));  
                    System.out.println("--------------------------------------");  
                }  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 關閉連線,釋放資源    
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    /** 
     * 傳送 post請求訪問本地應用並根據傳遞引數不同返回不同結果 
     */  
    public void post() {  
        // 建立預設的httpClient例項.    
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        // 建立httppost    
        HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");  
        // 建立引數佇列    
        List<namevaluepair> formparams = new ArrayList<namevaluepair>();  
        formparams.add(new BasicNameValuePair("type", "house"));  
        UrlEncodedFormEntity uefEntity;  
        try {  
            uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");  
            httppost.setEntity(uefEntity);  
            System.out.println("executing request " + httppost.getURI());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                HttpEntity entity = response.getEntity();  
                if (entity != null) {  
                    System.out.println("--------------------------------------");  
                    System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));  
                    System.out.println("--------------------------------------");  
                }  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 關閉連線,釋放資源    
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    /** 
     * 傳送 get請求 
     */  
    public void get() {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        try {  
            // 建立httpget.    
            HttpGet httpget = new HttpGet("http://www.baidu.com/");  
            System.out.println("executing request " + httpget.getURI());  
            // 執行get請求.    
            CloseableHttpResponse response = httpclient.execute(httpget);  
            try {  
                // 獲取響應實體    
                HttpEntity entity = response.getEntity();  
                System.out.println("--------------------------------------");  
                // 列印響應狀態    
                System.out.println(response.getStatusLine());  
                if (entity != null) {  
                    // 列印響應內容長度    
                    System.out.println("Response content length: " + entity.getContentLength());  
                    // 列印響應內容    
                    System.out.println("Response content: " + EntityUtils.toString(entity));  
                }  
                System.out.println("------------------------------------");  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 關閉連線,釋放資源    
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    /** 
     * 上傳檔案 
     */  
    public void upload() {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        try {  
            HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceFile.action");  
  
            FileBody bin = new FileBody(new File("F:\\image\\sendpix0.jpg"));  
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);  
  
            HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("bin", bin).addPart("comment", comment).build();  
  
            httppost.setEntity(reqEntity);  
  
            System.out.println("executing request " + httppost.getRequestLine());  
            CloseableHttpResponse response = httpclient.execute(httppost);  
            try {  
                System.out.println("----------------------------------------");  
                System.out.println(response.getStatusLine());  
                HttpEntity resEntity = response.getEntity();  
                if (resEntity != null) {  
                    System.out.println("Response content length: " + resEntity.getContentLength());  
                }  
                EntityUtils.consume(resEntity);  
            } finally {  
                response.close();  
            }  
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}

3.基於socket的網路連結操作

   (1)服務端

  1. 用指定的埠例項化一個SeverSocket物件。伺服器就可以用這個埠監聽從客戶端發來的連線請求。
  2. 呼叫ServerSocket的accept()方法,以在等待連線期間造成阻塞,監聽連線從埠上發來的連線請求。
  3. 利用accept方法返回的客戶端的Socket物件,進行讀寫IO的操作
  4. 關閉開啟的流和Socket物件
/**
 * 基於TCP協議的Socket通訊,實現使用者登入,服務端
*/
//1、建立一個伺服器端Socket,即ServerSocket,指定繫結的埠,並監聽此埠
ServerSocket serverSocket =newServerSocket(10086);//1024-65535的某個埠
//2、呼叫accept()方法開始監聽,等待客戶端的連線
Socket socket = serverSocket.accept();
//3、獲取輸入流,並讀取客戶端資訊
InputStream is = socket.getInputStream();
InputStreamReader isr =newInputStreamReader(is);
BufferedReader br =newBufferedReader(isr);
String info =null;
while((info=br.readLine())!=null){
System.out.println("Hello,我是伺服器,客戶端說:"+info);
}
socket.shutdownInput();//關閉輸入流
//4、獲取輸出流,響應客戶端的請求
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("Hello World!");
pw.flush();
  
 
//5、關閉資源
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();

(2)客戶端

  1. 用伺服器的IP地址和埠號例項化Socket物件。
  2. 呼叫connect方法,連線到伺服器上。
  3. 獲得Socket上的流,把流封裝進BufferedReader/PrintWriter的例項,以進行讀寫
  4. 利用Socket提供的getInputStream和getOutputStream方法,通過IO流物件,向伺服器傳送資料流
//客戶端
//1、建立客戶端Socket,指定伺服器地址和埠
Socket socket =newSocket("127.0.0.1",10086);
//2、獲取輸出流,向伺服器端傳送資訊
OutputStream os = socket.getOutputStream();//位元組輸出流
PrintWriter pw =newPrintWriter(os);//將輸出流包裝成列印流
pw.write("使用者名稱:admin;密碼:admin");
pw.flush();
socket.shutdownOutput();
//3、獲取輸入流,並讀取伺服器端的響應資訊
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info=br.readLine())!null){
 System.out.println("Hello,我是客戶端,伺服器說:"+info);
}
  
//4、關閉資源
br.close();
is.close();
pw.close();
os.close();
socket.close();

(3)多執行緒

  1. 伺服器端建立ServerSocket,迴圈呼叫accept()等待客戶端連線
  2. 客戶端建立一個socket並請求和伺服器端連線
  3. 伺服器端接受客戶端請求,建立socket與該客戶建立專線連線
  4. 建立連線的兩個socket在一個單獨的執行緒上對話
  5. 伺服器端繼續等待新的連線
//伺服器執行緒處理 和本執行緒相關的socket
Socket socket =null;
public serverThread(Socket socket){
this.socket = socket;
}
ServerSocket serverSocket =newServerSocket(10086);
Socket socket =null;
int count =0;//記錄客戶端的數量
while(true){
socket = serverScoket.accept();
ServerThread serverThread =newServerThread(socket);
 serverThread.start();
 count++;
System.out.println("客戶端連線的數量:"+count);
}