下面开始真正的网络编程分析。
对于网络传输,不得不提到网络模型, 网络从下到上分为如下几层:
物理层--数据链路层--网络层--传输层--会话层-- -表示层和应用层
ip协议--tcp协议 --- -- http协议,ftp协议,smtp协议等
手机能够使用互联网功能归根到底是手机底层实现了tcp/ip协议,可以使手机终端通过wifi或者中国移动/联通/电信数据流量建立tcp连接。tcp协议可以对上层提供统一的接口,使上层网络数据的传输建立在“无差别”的网络之上,而这个统一的接口就是socket。tcp/ip只是一个协议族,就像操作系统的运行机制一样,必须具体实现,同时还要提供对外的接口,就像win32是windows操作系统提供的对外接口一样,socket就是tcp/ip协议族提供的对上层应用的接口。从上面的分析不难看出,tcp/ip协议是网络通信必备,那么socket接口也是网络通信必备,无论是超文本传输,文件传输还是点对点通信,其本质都是调用tcp/ip协议的接口socket实现。但这里还有一个问题,我们在传输数据时可以只使用tcp/ip协议,但那样便无法识别传输内容,如果想要使传输的数据有意义,则必须使用到应用层协议,比如web使用http协议作为应用层协议,以封装http文本信息,然后通过tcp/ip协议将其发送到网络上。
在android中可以通过Socket和Http获取网络数据。
1、Socket通信
Java提供了ServerSocket类和Socket类实现客户端和服务端的通信,基本流程和Linux Socket通信一致。
第一,服务端创建套接字,绑定ip地址和端口,并设置为监听模式
第二,客户端创建套接字,连接服务端
第三,服务端收到客户端的请求后创建一个新的套接字与客户端进行通信
第四,客户端与服务端进行全双工通信,直到一方断开连接。
2、Http通信
Http协议采用的是请求-响应的模式,不仅在请求时需要先建立连接,而且需要客户端向服务器发送请求后,服务端才能回复数据。很多情况下,需要服务器主动向客户端推送数据,保持客户端与服务端数据的实时和同步。此时若建立的是Socket连接,服务器就可以直接将数据传送给客户端,但若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此客户端定时向服务器发送连接请求,不仅可以保持在线,同时也是询问服务端是否有新的数据,如果有就将其传送给客户端。
HTTP获取网路资源可以采用java原本就有的方法,也可以使用android仅有的方法,代码如下。
第一,java采用的方法
<span style="font-size:14px;"> URL url = null;
try {
url = new URL("http://www.baidu.com");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// 建立连接
URLConnection conn = url.openConnection();
// 设置参数,如要Post的内容
// conn.addRequestProperty(key, value);
DataInputStream dis = new DataInputStream(conn.getInputStream());
PrintWriter writer = new PrintWriter(conn.getOutputStream());
String str = "";
while(str != null){
str = dis.readUTF();
System.out.println(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}</span>
第二,android仅有的方法
<span style="font-size:14px;"> HttpClient client = new DefaultHttpClient();
// HTTP GET
HttpGet get = new HttpGet();
URI uri = null;
try {
uri = new URI("http://www.baidu.com");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
get.setURI(uri);
try {
HttpResponse result = client.execute(get);
InputStream input = result.getEntity().getContent();
DataInputStream dis = new DataInputStream(input);
String ss = dis.readLine();
tvIn.setText(ss);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// HTTP POST
HttpPost httpRequest = new HttpPost(uri);
List<NameValuePair> postParameters = null;
try {
httpRequest.setEntity(new UrlEncodedFormEntity(postParameters,HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpResponse httpresponse = new DefaultHttpClient().execute(httpRequest);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}</span>
http定义了与服务器的交互方法get/post,get的请求数据会附在uri之后,通过?隔开,而post的请求数据放在HTTP包体中,这样设置决定了post的安全级别比get高,而且get请求的数据有限,post请求的数据因为在HTTP包体中,比get请求的数据要多得多。