android 的网络编程一般可以分为两种:基于Socket的,基于Http的。
一、socket与Http
socket封装了TCP/IP协议,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输。socket通信方式是当服务器端与客户端建立起了socket连接后,服务器端可以直接将数据传输到客户端。(建立socket连接:建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。)
Http是应用层协议,Http是利用TCP在服务器和客户端之间传输信息的协议,主要解决如何包装数据。http通信方式是服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等
所以,Http通信方式可以看作为在Socket通信方式上对传输数据进行封装。Socket通信支持的TCP/IP协议相当于通信高速公路上的货车,负责运输任务;而Http则相当于货车上携带的货物,负责将要传输的数据包装为一个完整的货物。
二、socket通信编程实现
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.
客户端:
(1)用服务器的IP地址和端口号实例化Socket对象。
(2)将发送到服务器的IO流填充到IO对象里,比如BufferedReader/PrintWriter。
(3)利用Socket提供的getInputStream和getOutputStream方法,通过IO流对象,向服务器发送数据流。
(4) 通讯完成后,关闭打开的IO对象和Socket。
服务器端:
(1)在服务器,用一个端口来实例化一个 ServerSocket对象。此时,服务器就可以这个端口时刻监听从客户端发来的连接请求。
(2)调用ServerSocket的accept方法,开始监听连接从端口上发来的连接请求。
(3)利用accept方法返回的客户端的Socket对象,进行读写IO的操作
(4)通讯完成后,关闭打开的流和Socket对象。
代码:
public class Client {
private static InetAddress address;
private static int portNum=8888; public static void main(String[]args) throws Exception{
//获取本地IP
address=InetAddress.getByName("localhost"); //设置服务器端地址和连接端口号
Socket socket=new Socket(address,portNum);
//客户端向服务器端发送数据
PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true);
out.println("客户端向服务器端发送数据");
//接收服务器端数据
BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream())) ;
String serverMsg=in.readLine();
System.out.println("serverMsg "+serverMsg);
out.close();
in.close();
socket.close();
}
}
public class Server {
private static int portNo = 8888; public static void main(String[] args) throws IOException{
//设置服务器端与客户端连接的端口号,与客户端设置一致
ServerSocket serverSocket = new ServerSocket(portNo);
//等待接收客户端请求的socket
Socket socket = serverSocket.accept();
//向客户端发送数据
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println("这是服务器端向客户端发送的数据");
//接收客户端发送数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String clientMsg=in.readLine();
System.out.println("clientMsg "+clientMsg);
in.close();
out.close();
socket.close();
serverSocket.close();
}
}
三、Http通信编程实现(HttpURLConnection/HttpClient)
1、HttpURLConnection Java接口
private void httpUrlConnection() {
try {
//设置访问服务器地址
String pathUrl = "http://172.20.0.206:8082/TestServelt/login.do";
// 建立连接
URL url = new URL(pathUrl);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); //设置连接属性
httpConn.setDoOutput(true);// 使用 URL 连接进行输出
httpConn.setDoInput(true);// 使用 URL 连接进行输入
httpConn.setUseCaches(false);// 忽略缓存
httpConn.setRequestMethod("POST");// 设置URL请求方法
String requestString = "客服端要以以流方式发送到服务端的数据...";//设置请求数据 // 设置请求属性
// 获得数据字节数据,请求数据流的编码,必须和下面服务器端处理请求流的编码一致
byte[] requestStringBytes = requestString.getBytes(ENCODING_UTF_8);
httpConn.setRequestProperty("Content-length", "" + requestStringBytes.length);
httpConn.setRequestProperty("Content-Type", "application/octet-stream");
httpConn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
httpConn.setRequestProperty("Charset", "UTF-8");
//设置请求参数
String name = URLEncoder.encode("username", "utf-8");
httpConn.setRequestProperty("NAME", name); // 建立输出流,并将数据传输到服务器端
OutputStream outputStream = httpConn.getOutputStream();
outputStream.write(requestStringBytes);
outputStream.close();
// 获得响应状态
int responseCode = httpConn.getResponseCode();
if (HttpURLConnection.HTTP_OK == responseCode) {// 连接成功
// 当正确响应时处理数据
StringBuffer sb = new StringBuffer();
String readLine;
BufferedReader responseReader;
// 处理响应流,必须与服务器响应流输出的编码一致
responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), ENCODING_UTF_8));
while ((readLine = responseReader.readLine()) != null) {
sb.append(readLine).append("\n");
}
responseReader.close();
tv.setText(sb.toString());
}
} catch (Exception ex) {
ex.printStackTrace();
} }
2、HttpClient Apache接口
HttpClient是Apache提供的HTTP网络访问接口,从一开始就被引入到Android API中。它可以完成和HttpURLConnection几乎一模一样的效果,但两者之间的用法却有较大的差别。HttpClient是一个接口,android API中对这个接口有两个实现类AndroidHttpClient、DefaultHttpClient,一般android中对HttpClient的使用是通过DefaultHttpClient实现的。
发送带参数的get请求 //先将参数放入List,再对参数进行URL编码
List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
params.add(new BasicNameValuePair("param1", "中国"));
params.add(new BasicNameValuePair("param2", "value2"));
//对参数编码
String param = URLEncodedUtils.format(params, "UTF-8"); //baseUrl
String baseUrl = "http://ubs.free4lab.com/php/method.php"; //发送get请求需要创建HttpGet对象,然后将URL与参数拼接
HttpGet getMethod = new HttpGet(baseUrl + "?" + param); HttpClient httpClient = new DefaultHttpClient(); try {
//调用HttpClient的execute()方法发送请求
HttpResponse response = httpClient.execute(getMethod); //发起GET请求 if(response.getStatusLine().getStatusCode()==200){ //获取响应码 ,如果响应码为200,表示请求响应成功
//获取服务器响应内容
EntityUtils.toString(response.getEntity(), "utf-8");
} } catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
发送带参数的Post请求 //和GET方式一样,先将参数放入List
params = new LinkedList<BasicNameValuePair>();
params.add(new BasicNameValuePair("param1", "Post方法"));
params.add(new BasicNameValuePair("param2", "第二个参数")); try {
//发送Post请求需要先创建一个HttpPost对象
HttpPost postMethod = new HttpPost(baseUrl);
//将参数填入POST Entity中
postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8")); //执行POST方法,发送请求
HttpResponse response = httpClient.execute(postMethod);
if(response.getStatusLine().getStatusCode()==200){//获取响应码
//获取响应内容
String result=EntityUtils.toString(response.getEntity(), "utf-8")
} } catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}