zoukankan      html  css  js  c++  java
  • 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 /**
    19 * 创建一个SocketServer对象用来建立服务器
    20 * @throws IOException
    21 */
    22 public static void CreateServer() throws IOException
    23 {
    24 serverSocket = new ServerSocket(port,10);
    25 System.out.println("start listening...");
    26 }
    27
    28 /**
    29 * 创建一个Socket对象用来连接SocketServer对象
    30 * @param dstName Server对象的ip地址
    31 * @return
    32 * @throws IOException
    33 */
    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 /**
    42 * 返回一个已经连接到服务器上的Socket对象
    43 * @throws IOException
    44 */
    45 public static void GetClinetSocket() throws IOException
    46 {
    47 client = serverSocket.accept();
    48 System.out.println("get a connected client");
    49 }
    50
    51 /**
    52 * 向socket对象所获取的流中发送数据
    53 * @param socket
    54 * @param msg
    55 * @throws IOException
    56 */
    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 /**
    66 * 获取socket对象流中数据
    67 * @param socket
    68 * @param msg
    69 * @return
    70 * @throws IOException
    71 */
    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 /**
    81 * 释放socket对象
    82 * @throws IOException
    83 */
    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 /**
    13 * Http中的get请求,在Url中带有请求的参数,请求的URL格式通常为:"http://XXX.XXXX.com/xx.aspx?param=value"
    14 * 在android中默认的http请求为get方式
    15 * @return
    16 * @throws IOException
    17 */
    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     /**
    2 * Http中的post请求,不在Url中附加任何参数,这些参数都会通过cookie或者session等其他方式以键值对的形式key=value传送到服务器上,完成一次请求
    3 * 请求的URL格式通常为:"http://XXX.XXXX.com/xx.aspx"
    4 * @param param 请求的键名
    5 * @param value 请求的数据值
    6 * @throws IOException
    7 */
    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<NameValuePair> params = new ArrayList<NameValuePair>();
    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 }
  • 相关阅读:
    高精度计算
    高精度除以低精度
    P1258 小车问题
    POJ 2352 stars (树状数组入门经典!!!)
    HDU 3635 Dragon Balls(超级经典的带权并查集!!!新手入门)
    HDU 3938 Portal (离线并查集,此题思路很强!!!,得到所谓的距离很巧妙)
    POJ 1703 Find them, Catch them(确定元素归属集合的并查集)
    HDU Virtual Friends(超级经典的带权并查集)
    HDU 3047 Zjnu Stadium(带权并查集,难想到)
    HDU 3038 How Many Answers Are Wrong(带权并查集,真的很难想到是个并查集!!!)
  • 原文地址:https://www.cnblogs.com/qchy/p/2985882.html
Copyright © 2011-2022 走看看