天天看點

Android網絡程式設計一:Socket、Http

轉自:http://blog.csdn.net/xiangjai/article/details/7835023

正文

  在Android的網絡通訊中,通常會使用

  Socket進行裝置間數的資料通訊,

Http來對網絡資料進行請求。

  1、Socket(套接字)

不管是有過Java開發經驗還是.NET開發經驗的同學都應該對Socket有或多或少的了解,常見的TCP或者UDP協定其實都是基于Socket來實作的。

Socket是用于描述網絡上的一個裝置中的一個程序或者應用程式的,Socket由IP位址和端口号兩部分組成。IP位址用來定位裝置,端口号用來定位應用程式或者程序,比如我們常見的運作在80端口上的HTTP協定。Socket的常見格式為:192.168.1.1:1234。

那麼應用程式是如何通過Socket來與網絡中的其他裝置進行通訊的呢?通常情況下,Socket通信有兩部分,一部分為監聽的Server端,一部分為主動請求連接配接的Client端。Server端會一直監聽Socket中的端口直到有請求為止,當Client端對該端口進行連接配接請求時,Server端就給予應答并傳回一個Socket對象,以後在Server端與Client端的資料交換就可以使用這個Socket來進行操作了。

  2、Android中使用Socket進行資料交換

ServerSocket

  建立服務端(Server)時,需要使用ServerSocket對象,這個對象會自動對其構造函數中傳入的端口号進行監聽,并在收到連接配接請求後,使用ServerSocket.accept()方法傳回一個連接配接的的Socket對象。這個方法并不需要我們像在.NET中那樣使用Start方法,它會自動進行監聽的。

Socket

  不管建立用戶端(Client)還是在進行其他資料交換方面的操作時,都需要使用Socket類。Socket類在進行初始化時需要出入Server端的IP位址和端口号,并傳回連接配接到Server端的一個Socket對象,如果是連接配接失敗,那麼将傳回異常。同ServerSocket,也是自動進行連接配接請求的。

  通過上面兩個步驟後,Server端和Client端就可以連接配接起來了,但是僅僅連接配接起來是沒有任何作用的,資料交換才是我們的目的,這時候就需要用到IO流中的OutputStream類和InputStream類。

OutputStream——可寫流

  當應用程式需要對流進行資料寫操作時,可以使用Socket.getOutputStream()方法傳回的資料流進行操作。

InputStream——可讀流

  當應用程式要從流中取出資料時,可以使用Socket.getInputStream()方法傳回的資料流進行操作。

  看看完整的代碼吧

View Code

1 package LiB.Demo;

2

3 import java.io.BufferedReader;

4 import java.io.BufferedWriter;

5 import java.io.IOException;

6 import java.io.InputStreamReader;

7 import java.io.OutputStreamWriter;

8 import java.net.ServerSocket;

9 import java.net.Socket;

10

11 public class SocketHelper {

12 private static ServerSocket serverSocket = null;

13 private static Socket client = null;

14 private final static int port = 9048;

15 private static BufferedReader br= null;

16 private static BufferedWriter bw = null;

17

18

22 public static void CreateServer() throws IOException

23 {

24 serverSocket = new ServerSocket(port,10);

25 System.out.println(“start listening…”);

26 }

27

28

34 public static Socket CreateClient(String dstName) throws IOException

35 {

36 Socket socket = new Socket(dstName, port);

37 //Socket sockets = new Socket(“192.168.8.12”,port);

38 return socket;

39 }

40

41

45 public static void GetClinetSocket() throws IOException

46 {

47 client = serverSocket.accept();

48 System.out.println(“get a connected client”);

49 }

50

51

57 public static void SendMsg(Socket socket , String msg) throws IOException

58 {

59 bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

60 bw.write(msg);

61 bw.flush();

62 bw.close();

63 }

64

65

72 public static String ReceiveMsg(Socket socket, String msg) throws IOException

73 {

74 br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

75 String receiveMsg = “Receive msg:”+ br.readLine();

76 br.close();

77 return receiveMsg;

78 }

79

80

84 public static void Close() throws IOException

85 {

86 if(client != null)

87 {

88 client.close();

89 }

90 if(serverSocket != null)

91 {

92 serverSocket.close();

93 }

94 }

95 }

3、HTTP通訊

  在開始前先簡單介紹下HTTP協定中的兩種不同的請求方式——GET和POST。GET方式在進行資料請求時,會把資料附加到URL後面傳遞給伺服器,比如常見的:http://XXX.XXX.XXX/XX.aspx?id=1,POST方式則是将請求的資料放到HTTP請求頭中,作為請求頭的一部分傳入伺服器。是以,在進行HTTP程式設計前,首先要明确究竟使用的哪種方式進行資料請求的。

  在Android中,可以有兩種方式可以用來進行Http程式設計:

  1、HttpURLConnection;

  2、HttpClient。

HttpURLConnection

  HttpURLConnection是繼承自URLConnection的一個抽象類,在HTTP程式設計時,來自HttpURLConnection的類是所有操作的基礎,擷取該對象的代碼如下:

View Code

1 public HttpURLConnection urlconn= null;

2 private void Init() throws IOException

3 {

4 if (urlStr==”“)

5 {

6 urlStr=”http://www.baidu.com”;

7 }

8 URL url = new URL(urlStr);

9 //打開一個URL所指向的Connection對象

10 urlconn = (HttpURLConnection)url.openConnection();

11 }

  HttpURLConnection對網絡資源的請求在預設情況下是使用GET方式的,是以當使用GET方式時,不需要我們做太多的工作:

View Code

1 public HttpURLConnection urlconn= null;

2 private void Init() throws IOException

3 {

4 if (urlStr==”“)

5 {

6 urlStr=”http://www.baidu.com”;

7 }

8 URL url = new URL(urlStr);

9 //打開一個URL所指向的Connection對象

10 urlconn = (HttpURLConnection)url.openConnection();

11 }

12

18 public String HttpGetMethod() throws IOException

19 {

20 if(urlconn == null)

21 {

22 Init();

23 }

24 String result = StreamDeal(urlconn.getInputStream());

25 urlconn.disconnect();

26 return result;

27 }

  當我們需要使用POST方式時,就需要使用setRequestMethod()來設定請求方式了。

View Code

1

8 public String HttpPostMethod(String key,String value) throws IOException

9 {

10 if (urlconn==null)

11 {

12 Init();

13 }

14 //設定該URLConnection可讀

15 urlconn.setDoInput(true);

16 //設定該URLConnection可寫

17 urlconn.setDoOutput(true);

18 //使用POST方式來送出資料

19 urlconn.setRequestMethod(“POST”);

20 //不運作緩存

21 urlconn.setUseCaches(false);

22 //當使用POST方式進行資料請求時,我們可以手動執行connect動作,當然,這個動作其實在getOutputStream()方法中會預設執行的

23 //上面那些設定URLConnection屬性的動作,一定要在connect動作執行前,因為一旦動作已經執行,熟悉設定就沒有任何作用了

24 urlconn.connect();

25 //使用POST方式時,我們需要自己構造部分Http請求的内容,是以我們需要使用OutputStream來進行資料寫如操作

26 OutputStreamWriter writer = new OutputStreamWriter(urlconn.getOutputStream());

27

28 String urlQueryStr = key+”=”+URLEncoder.encode(value, “Utf-8”);

29 writer.write(urlQueryStr);

30

31 writer.flush();

32 writer.close();

33 //擷取傳回的内容

34 String result = StreamDeal(urlconn.getInputStream());

35 return result;

36

37 }

HttpClient

  這個類并不是來自Android的,而是來自org.apache.http。和HttpURLConnection相同,HttpClient也存在GET和POST兩種方式。

HttpGet

  在HttpClient中,我們可以非常輕松使用HttpGet對象來通過GET方式進行資料請求操作,當獲得HttpGet對象後我們可以使用HttpClient的execute方法來向我們的伺服器發送請求。在發送的GET請求被伺服器相應後,會傳回一個HttpResponse響應對象,利用這個響應的對象我們能夠獲得響應回來的狀态碼,如:200、400、401等等。

View Code

1 public String HttpGetMethod()

2 {

3 String result = “”;

4 try

5 {

6 HttpGet httpRequest = new HttpGet(urlStr);

7 HttpClient httpClient = new DefaultHttpClient();

8 HttpResponse httpResponse = httpClient.execute(httpRequest);

9 if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)

10 {

11 result = EntityUtils.toString(httpResponse.getEntity());

12 }

13 else

14 {

15 result = “null”;

16 }

17 return result;

18 }

19 catch(Exception e)

20 {

21 return null;

22 }

23 }

HttpPost

  當我們使用POST方式時,我們可以使用HttpPost類來進行操作。當擷取了HttpPost對象後,我們就需要向這個請求體傳入鍵值對,這個鍵值對我們可以使用NameValuePair對象來進行構造,然後再使用HttpRequest對象最終構造我們的請求體,最後使用HttpClient的execute方法來發送我們的請求,并在得到響應後傳回一個HttpResponse對象。其他操作和我們在HttpGet對象中的操作一樣。

View Code

1 public String HttpPostMethod(String key,String value)

2 {

3 String result = “”;

4 try

5 {

6 // HttpPost連接配接對象

7 HttpPost httpRequest = new HttpPost(urlStr);

8 // 使用NameValuePair來儲存要傳遞的Post參數

9 List params = new ArrayList();

10 // 添加要傳遞的參數

11 params.add(new BasicNameValuePair(key, value));

12 // 設定字元集

13 HttpEntity httpentity = new UrlEncodedFormEntity(params, “Utf-8”);

14 // 請求httpRequest

15 httpRequest.setEntity(httpentity);

16 // 取得預設的HttpClient

17 HttpClient httpclient = new DefaultHttpClient();

18 // 取得HttpResponse

19 HttpResponse httpResponse = httpclient.execute(httpRequest);

20 // HttpStatus.SC_OK表示連接配接成功

21 if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {

22 // 取得傳回的字元串

23 result = EntityUtils.toString(httpResponse.getEntity());

24 return result;

25 } else {

26 return “null”;

27 }

28 }

29 catch(Exception e)

30 {

31 return null;

32 }

33 }

繼續閱讀