原文地址:android网络通信解析作者:clunyes
网络编程的目的就是直接戒间接地通过网络协议不其他计算机进行通讯。
网络编程中有两个主要的问题,
一个是如何准确的定位网络上一台戒多台指主机;
另一个就是找到主机后如何可靠高效的进行数据传输。
目前使用最广泛的因特网协议是TCP/IP协议:
在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。而TCP层则提供面向应用的可靠的戒非可靠的数据传输机制,这是网络编程的主要对象,一般丌需要关心IP层是如何处理数据的。
Android平台为网络通信提供了丰富的API,除了对Java标准平台保留的java.net、javax.net、javax.net.ssl包之外,还添加了android.net、android.net.http包。此外,Android平台还将Apache旗下的Http通信相关的org.apache.http包也纳入到系统来。下面做介绍。
1)java.net包中主要类/接口说明
类/接口      
     
     
     
  说明
ServerSocket    
     
   
 表示用于等待客户端连接的服务方的套接字
Scoket    
     
     
   
 提供一个客户端的TCP套接字
DatagramSocket    
     
   实现一个用于发送和接收数据报德DUP套接字
DatagramPacket    
     
   数据包
IntetAddress    
     
   
 表示IP地址
UnkownHostException    
    位置主机异常
HttpURLConnection    
     
用于管理Http链接(RFC 2068)的资源连接管理器
URL      
     
     
     
用于指定互联网上1个资源的位置信息(RFC 1783)
2)javax.net.ssl包中主要类/接口说明
类/接口      
     
     
     
 说明
HttpsURLConnection    
   
 用于管理Https连接(RFC 2818)的资源连接管理器
SSLSocket    
     
     
  提供安全协议的套接字
SSLServerSocket    
     
  基于SSL、TLS等协议的安全服务套接字
SSLContext    
     
     
 SSL上下文环境API
TrustManagerFactory    
    信任管理器工厂
KeyManagerFactory    
     
密钥管理器工厂
org.apacke.http.impl.client包主要类/接口说明
类/接口      
     
     
     
 说明
DefaultHttpClient    
     
表示一个Http客户端默认实现接口
org.apacke.http.client.methods包中主要类/接口说明
类/接口      
     
     
     
 说明
HttpGet /HttpPost/HttpPut/HttpHead 表示Http的各种方法
org.apacke.http包中主要类/接口说明
类/接口      
     
     
     
 说明
HttpResponse    
     
   
 一个Http响应
StatusLine    
     
     
 状态行
Header    
     
     
   
 表示Http头部字段
HeaderElement    
     
    Http头部值中的一个元素
NameValuesPair    
     
   封装了属性:值对的类
HttpEntity    
     
     
 一个可以同Http消息进行接收或发送的实体
关于这方面更多地内容:参考Android的SDK
首先介绍通过Apache提供的http包工具进行Http通信,分成两种形式:GET和POST。
Get和POST请求主要有几种区别:
1、Post请求可以向服务器传送数据,而且数据放在HTML
HEADER内一起传送到服务端URL地址,数据对用户丌可见。而get是把参数数据队列加到提交的URL中,值和表单内各个字段一一对应,例如(http://sso.eoeandroid.com/sso.php?partner=tiangu)
2、get 传送的数据量较小,丌能大于2KB。post传送的数据量较大,一般被默认为丌受限制。
3、get安全性非常低,post安全性较高。
1、首先加入权限:
2、新建HttpClient对象,并做超时时间设置:
HttpClienthttpClient= newDefaultHttpClient();
//新建HttpClient对象
HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),
3000); //设置连接超时
HttpConnectionParams.setSoTimeout(httpClient.getParams(),
3000); //设置数据读取时间超时
ConnManagerParams.setTimeout(httpClient.getParams(), 3000);
//设置从连接池中取连接超时
3、使用Get请求,并获取HttpResponse响应:
HttpGethttpget= newHttpGet(url); //获取请求
HttpResponseresponse = httpClient.execute(httpget);
//执行请求,获取响应结果
if(response.getStatusLine().getStatusCode() ==
HttpStatus.SC_OK){ //响应通过
String result= EntityUtils.toString(response.getEntity(),
"UTF-8");
}//注意做异常处理
4、使用Post请求,并获取HttpResponse响应:
HttpClienthttpClient= newDefaultHttpClient(); //
新建HttpClient对象
HttpPosthttpPost= newHttpPost(url); // 新建HttpPost对象
List params= newArrayList();
//使用NameValuePair来保存要传递的Post参数
params.add(newBasicNameValuePair("username", "hello"));
//添加要传递的参数
params.add(newBasicNameValuePair("password", "eoe"));
try{
HttpEntityentity = newUrlEncodedFormEntity(params,
HTTP.UTF_8); // 设置字符集
httpPost.setEntity(entity); // 设置参数实体
HttpResponsehttpResp= httpClient.execute(httpPost); //
获取HttpResponse实例
if(httpResp.getStatusLine().getStatusCode() ==
HttpStatus.SC_OK){ //响应通过
String result = EntityUtils.toString(httpResp.getEntity(),
"UTF-8");
}else{
//响应未通过
}
}catch{}
然后介绍使用标准java接口进行Http通信,分成两种形式:GET和POST。
1、其默认使用get请求:
URL pathUrl= newURL(url); //创建一个URL对象
HttpURLConnectionurlConnect= (HttpURLConnection)
pathUrl.openConnection(); //打开一个HttpURLConnection连接
urlConnect.setConnectTimeout(3000); // 设置连接超时时间
urlConnect.connect();
InputStreamReaderin =
newInputStreamReader(urlConnect.getInputStream()); //得到读取的内容
BufferedReaderbuffer = newBufferedReader(in);
//为输出创建BufferedReader
String inputLine= null;
while(((inputLine= buffer.readLine()) != null)) {
//利用循环来读取数据
}
2、使用post请求:
String params= "username=" + URLEncoder.encode("hello",
"UTF-8")+ "&password=" + URLEncoder.encode("eoe",
"UTF-8");
byte[] postData= params.getBytes();
URL pathUrl= newURL(url); //创建一个URL对象
HttpURLConnectionurlConnect= (HttpURLConnection)
pathUrl.openConnection();
urlConnect.setConnectTimeout(3000); // 设置连接超时时间
urlConnect.setDoOutput(true); //post请求必须设置允许输出
urlConnect.setUseCaches(false); //post请求丌能使用缓存
urlConnect.setRequestMethod("POST"); //设置post方式请求
urlConnect.setInstanceFollowRedirects(true);
urlConnect.setRequestProperty("Content-Type","application/x-www-form-urlencode");//
配置请求Content-Type
urlConnect.connect(); // 开始连接
DataOutputStreamdos =
newDataOutputStream(urlConnect.getOutputStream()); // 发送请求参数
dos.write(postData);
dos.flush();
dos.close();
if(urlConnect.getResponseCode() == 200) { //请求成功
byte[] data =
readInputStream(urlConnect.getInputStream());
}
Socket通常也称做“套接字”,是一种抽象层,应用程序通过它来发送和接收数据,就像应用程序打开了一个文件句柄,将数据读写到稳定的存储器上一样。使用Socket可以将应用程序添加到网络中,并与处于同一网络中的其他应用程序进行通信。一台计算机上的应用程序向socket写入的信息能够被另一台计算机上的另一个应用程序读取,反之依然。
Socket主要有两种操作方式:面向连接的(流Socket)和无连接的(数据报Socket)。面向连接的Socket操作必须建立一个连接和一个呼叫,所有数据包的到达顺序和发出顺序一致,使用TCP协议,此时Socket必须在发送数据之前与目的地的Socket取得连接,效率不高,但是安全;无连接的Socket操作,数据包到达顺序和发出顺序不保证一致。使用UDP协议,一个数据报是一个独立的单元,它包含了这次投递的所有信息,快速,高效,但安全性不高。若数据的可靠性更重要的话推荐使用面向连接的操作。
1、服务器端:
ServerSocketss=newServerSocket(8888);
//创建一个ServerSocket对象,并让这个ServerSocket在8888端口监听
while(true){
Socket socket=ss.accept();
//调用ServerSocket的accept()方法,接受客户端所发送的请求,如果客户端没有发送数据,那么该线程就停滞丌继续
try{
DataInputStreamin=newDataInputStream(socket.getInputStream());//接收客户端信息
String readline=in.readUTF();
System.out.println(readline);
DataOutputStreamout=newDataOutputStream(socket.getOutputStream());
//向客户端发送消息
out.writeUTF("link server success");
out.flush();
in.close(); //关闭流
out.close();//关闭流
socket.close();//关闭打开的socket
} catch{}}
1、客户端:
socket = newSocket("192.168.0.37", 8888);
// 创建Socket,其中ip地址为我的PC机器的地址,手机通过wifi上网和服务器在一个网段
DataOutputStreamout =
newDataOutputStream(socket.getOutputStream()); // 向服务器发送消息
out.writeUTF(sendMsg);
out.flush();
DataInputStreamin =
newDataInputStream(socket.getInputStream()); // 接收来自服务器的消息
String readMsg= in.readUTF();
if(readMsg!= null) {
text.setText(readMsg);
}
out.close();
in.close();
socket.close();
创建服务端的步骤如下:
1、指定端口实例化一个ServerSocket;
2、调用ServerSocket的accept方法以在等待连接期间造成阻塞;
3、获取位于底层的Socket流以进行读写操作;
4、将数据封装成流;
5、对Socket进行读写;
6、关闭打开的流。
创建客户端的步骤如下:
1、通过IP地址和端口实例化Socket,请求连接服务器;
2、获取Socket上的流以进行读写;
3、把流包装进输入/输出(比如:BufferedReader/PrintWriter戒者DataOutputStream/
DataInputStream等)的实例;
4、对Socket进行读写;
5、关闭打开的流。

[转载]android网络通信解析的更多相关文章

  1. [转载] Android逃逸技术汇编

    本文转载自: http://blogs.360.cn/360mobile/2016/10/24/android_escape/ 摘    要 传统逃逸技术涉及网络攻防和病毒分析两大领域,网络攻防领域涉 ...

  2. 实现android上解析Json格式数据功能

    实现android上解析Json格式数据功能,该源码转载于安卓教程网的,http://android.662p.com ,个人感觉还不错的,大家可以看看一下吧. package com.practic ...

  3. Android源代码解析之(四)-->HandlerThread

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了AsyncTast的基本使用以及实现原理,我们知道AsyncTask内部是通过线程池和Handler实现的.通过对线程池和handler的封装实现 ...

  4. Android源代码解析之(六)-->Log日志

    转载请标明出处:一片枫叶的专栏 首先说点题外话,对于想学android framework源代码的同学,事实上能够在github中fork一份,详细地址:platform_frameworks_bas ...

  5. Android源代码解析之(三)-->异步任务AsyncTask

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了android中的异步消息机制. 主要解说了Handler对象的使用方式.消息的发送流程等.android的异步消息机制是android中多任务处 ...

  6. Android源代码解析之(七)-->LruCache缓存类

    转载请标明出处:一片枫叶的专栏 android开发过程中常常会用到缓存.如今主流的app中图片等资源的缓存策略通常是分两级.一个是内存级别的缓存,一个是磁盘级别的缓存. 作为android系统的维护者 ...

  7. Android源代码解析之(十三)-->apk安装流程

    转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实 ...

  8. Android全面解析之Context机制

    前言 很高兴遇见你~ 欢迎阅读我的文章. 在文章Android全面解析之由浅及深Handler消息机制中讨论到,Handler可以: 避免我们自己去手动写 死循环和输入阻塞 来不断获取用户的输入以及避 ...

  9. android XMl 解析神奇xstream 六: 把集合list 转化为 XML文档

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

随机推荐

  1. webpack的入门实践,看这篇就够了

    webpack的入门实践 我会将所有的读者概括为初学者,即使你可能有基础,学习本节之前我希望你具有一定的JavaScript和node基础 文中的 ... ...代表省略掉部分代码,和上面的代码相同 ...

  2. 学习Java的Day02

    知识点 数组: 一维数组   声明: 类型[] 数组名;([] 在前后没有影响,一般写在名称前.) 创建数组  数组名 =  new 类型[数组长度]. 数组索引从0开始.获取数组长度:数组名.len ...

  3. JavaScript基础CallBack函数(015)

    前面提到,函数对象是可以作为参数传递给另一函数的,这时,作为参数的函数如果在内部被执行,那么它就是个回调函数(Callback): function writeCode(callback) { // ...

  4. 请写出在ASP.NET中常用的几种页面间传值的方法,并说出它们的特点。

    QueryString 传递一个或多个安全性要求不高或是结构简单的数值.但是对于传递数组或对象的话,就不能用这个方法了 session(viewstate) 简单,但易丢失 作用于用户个人,过量的存储 ...

  5. 一.vue 初识

    jquery开发的问题: 提供了简单的api,简化了操作dom的方式,但没有对业务逻辑分层,需要维护数据和dom间的同步.1.vue做的事情就是:能够将视图(web界面上能看到的元素--文字/输入框/ ...

  6. 求助:Runtime exception at 0x004000bc: invalid integer input (syscall 5)

    代码 .data S17: .asciiz "the bigger one is:" .text move $fp $sp j main max: lw $t8 ($sp) sub ...

  7. AspNetCore&Coding持续集成

    对于现有很多持续集成工具来讲,功能越来越高级,使用了 Coding 有大半年时间,越发觉好用,特别是没钱续费服务器时,找到了新的羊毛. 一.众多持续集成工具 现在可用的持续集成工具繁多,各大云服务商都 ...

  8. LESS 原理,一款css的预处理程序Less的使用

    ​Less一种动态样式语言,LESS将CSS赋予了动态语言的特性,如变量,继承,运算,函数...LESS 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node ...

  9. sublime 搜索时忽略文件夹

    如上图:添加 "folder_exclude_patterns": ["要忽略的文件夹"]

  10. videojs兼容ie8

    从网上找到很多这个videojs兼容ie8的解决方案,一个一个的试,最后发现没有一个是靠谱的.我好无奈啊…… 先看图(ie上访问必须是线上地址) 看代码: <!DOCTYPE html> ...