Android应用开发揭秘(笔记) 第八章网络通信

来源:互联网 发布:java注解反射原理 编辑:程序博客网 时间:2024/05/17 01:00

☆ 目前Android平台有3种网络接口可以使用,他们分别是:java.net.*(标准java接口)、org.apache(Apache接口)和android.net.*(Android网络接口)。
1. 标准Java接口:提供与联网有关的类,包括流和数据包套接字、Internet协议、常见HTTP处理。
代码如下:
try{
URL url = new URL("http://www.google.com");//定义地址
HttpURLConnection http = url.openConnection();//打开连接
int nRc = http.getResponseCode();//得到连接状态
if( nRc == HttpURLConnection.HTTP.OK ){
InputStream is = http.getInputStream();
//处理数据...
}

}catch( Exception e){

}
2. Apache接口:可以将Apache视为目前流行的开源Web服务器,主要包括创建HttpClient以及Get/Post、HttpRequest等对象,设置连接参数,执行HTTP操作,处理服务器
返回结果等功能。
代码如下:
try{
HttpClient hc = new DefaultHttpCilent();
HttpGet get = new HttpGet("http://www.google.com");
HttpResoponse rp = hc.execute(get);
if( rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK ){
InputStream is = rp.getEntity().getContent();
//处理数据...
}


}catch(Exception e){

}

3.Android网络接口:android.net.*包实际上是通过对Apache中HttpClient的封装来实现的一个HTTP编程接口,同时还提供了HTTP请求队列管理以及
HTTP连接池管理,以提高并发请求情况下(如装载网页时)的处理效率,除此之外还有网络状态监视等接口、网络访问的Socket、常用的Uri类以及有
关Wifi相关的类等等。
如下代码为简单的Socket连接。
try{
//IP地址
InetAddress inetAddress = InetAddress.getByName("192.168.1.110");
//端口
Socket client = new Socket( inetAddress, 61203, true );
//取得数据
InputStream in = clinet.getInputStream();
OuputStream out = clinet.getOuputStream();
//处理数据...
out.close();
in.close();
clinet.close();

}catch(Exception e){

}

☆ HTTP通信:
HTTP(Hyper Text Transfer Protocol,超文本传输协议)。
Android提供了HttpURLConnection 和 HttpClient接口来开发HTTP程序。
1.HttpURLConnection接口:
HTTP 通信中使用最多的就是Get 和Post,Get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给服务器。Post与Get的不同之处在于Post参数是不放在URL字串里,
而是放在Http请求数据中。HttpURLConnection是java标准类,继承自URLConnection类,URLConnection与HttpURLConnection都是抽象类,无法直接实例化对象。
其对象主要通过URL的openConnection方法获得,创建一个HttpURLConnection连接代码如下:
URL url = new URL("http://www.google.com");
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
openConnection方法只是创建URLConnection或者HttpURLConnection实例,但并不是真正连接操作。每次openConnecion都将创建一个新的实例。因此在连接之前我们可以对其一些
属性进行设置,比如超时时间等。下面是对HttpURLConnection实例的属性设置:
urlConn.setDoOutput(true);//设置输入(输出)流
urlConn.setDoInput(true);
urlConn.setRequestMethod("POST");//设置连接方式为POST
urlConn.setUseCaches(false);//请求不能使用缓存
urlConn.disconnect();//关闭HttpURLConnection连接。

2.不需要参数访问网页 代码如下:
//http地址
String httpUrl = "http://192.168.1.110:8080/http1.jsp";
//获得的数据
String resultData = "";
URL url = null;
try
{
//构造一个URL对象
url = new URL(httpUrl);
}
catch (MalformedURLException e)
{
Log.e(DEBUG_TAG, "MalformedURLException");
}
if (url != null)
{
try
{
//使用HttpURLConnection打开连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//得到读取的内容(流)
InputStreamReader in = new InputStreamReader(urlConn.getInputStream());
// 为输出创建BufferedReader
BufferedReader buffer = new BufferedReader(in);
String inputLine = null;
//使用循环来读取获得的数据
while (((inputLine = buffer.readLine()) != null))
{
//我们在每一行后面加上一个"\n"来换行
resultData += inputLine + "\n";
}
//关闭InputStreamReader
in.close();
//关闭http连接
urlConn.disconnect();
//设置显示取得的内容
if ( resultData != null )
{
mTextView.setText(resultData);
}
else
{
mTextView.setText("读取的内容为NULL");
}
}
catch (IOException e)
{
Log.e(DEBUG_TAG, "IOException");
}



3.以POST为连接方式,带参数显示网页的代码如下:
//http地址"?par=abcdefg"是我们上传的参数
String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
//获得的数据
String resultData = "";
URL url = null;
try
{
//构造一个URL对象
url = new URL(httpUrl);
}
catch (MalformedURLException e)
{
Log.e(DEBUG_TAG, "MalformedURLException");
}
if (url != null)
{
try
{
// 使用HttpURLConnection打开连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//因为这个是post请求,设立需要设置为true
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
// 设置以POST方式
urlConn.setRequestMethod("POST");
// Post 请求不能使用缓存
urlConn.setUseCaches(false);
urlConn.setInstanceFollowRedirects(true);
// 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
// 要注意的是connection.getOutputStream会隐含的进行connect。
urlConn.connect();
//DataOutputStream流
DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
//要上传的参数
String content = "par=" + URLEncoder.encode("ABCDEFG", "gb2312");
//将要上传的内容写入流中
out.writeBytes(content);
//刷新、关闭
out.flush();
out.close();
//获取数据
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String inputLine = null;
//使用循环来读取获得的数据
while (((inputLine = reader.readLine()) != null))
{
//我们在每一行后面加上一个"\n"来换行
resultData += inputLine + "\n";
}
reader.close();
//关闭http连接
urlConn.disconnect();
//设置显示取得的内容
if ( resultData != null )
{
mTextView.setText(resultData);
}
else
{
mTextView.setText("读取的内容为NULL");
}
}
catch (IOException e)
{
Log.e(DEBUG_TAG, "IOException");
}
☆ HttpClient接口:
Apache提供了HttpClient,它对java.net中类做了封装和抽象,更适合我们在Android 上开发联网应用。
1.ClientConnectionManager接口:是客户端连接管理接口,他提供以下几个抽象方法。
closeIdleConnection 关闭空闲的连接
releaseConnection 释放一个连接
requestConnection 请求一个新的连接
shutdown 关闭管理器并释放资源。

2.DefaultHttpClient:默认的一个HTTP客户端,我们可以使用它创建一个HTTP连接。代码如下:
HttpClient httpclient = new DefaultHttpClient();

3.HttpResponse:是一个HTTP连接响应,当执行一个HTTP连接后,就会返回一个HttpResponse,可以通过HttpResponse得到一些响应信息。
HttpResponse httpResponse = httpclient.execute( httpRequeset );
if( httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK ){
//连接成功
}

☆ Socket 通信:
Socket又称套接字,由于描述IP和端口,是一个通信链的句柄。
应用程序通过“套接字”向网络发出请求或者应答网络请求。它是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。
Socket通信必须包含的5种信息:
1.连接使用的协议。
2.本地主机的IP地址。
3.本地进程的协议端口。
4.远地主机的IP地址和远地进程的协议端口。
Socket传输模式:面向连接和无连接。面向连接的Socket操作就像一部电话,必须建立一个连接一个呼叫。所有事情到达的顺序与它发出时的顺序是一样的。
无连接的Socket操作就像一个邮件投递,没有什么保证,多个邮件到达时的顺序可能与出发的顺序不一样。
面向连接的操作使用TCP协议。一个这个模式下的Socket必须在发送数据之前与目的地的Socket取得连接。一旦连接建立了,Socket就可以使用一个流接口进行打开、
读、写、关闭操作。所有发送的信息都会在另一端以同样的顺序被接受。面向连接的操作比无连接操的效率更低,旦数据的安全性高。

Socket编程原理:
1.Socket构造:
Java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。
在选择端口时需要小心,每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0-1023的端口为系统保留。我们在选择端口时最好选择一个大于1023的数,
防止放生冲突。

2.客户端Socket:
要想使用Socket来与一个服务器通信,就必须现在客户端创建一个Socket,并指出需要连接的服务器的IP地址和端口。
代码如下:
try{
//192.168.1.110是IP地址,54321是端口
Socket socket = new Socket("192.168.1.110", 54321);

}catch( IOException e ){

}

3.ServerSocket:
try{
ServerSocket server = ServerSocket(54321);
}catch( IOException e ){}

try{
Socket socket = server.accept();//等待客户的请求,直到有一个客户启动并请求连接到相同的端口。
}catch( IOException e ){}
上面的代码是创建一个ServerSocket在端口54321监听客户请求,它是Server的典型工作模式,在这里Server只能接收一个请求,接收后Server就退出了。

4.输入(出)流:
Socket提供了getInputStream()和getOutputStream()来得到对应的输入(出)流以进行读(写)操作。这两个方法分别返回InputStream和OutputStream类对象。
为了便于读写数据,我们可以在返回的输入/输出流对象中建立过滤流,如DataInputStream、DataOutputStream或PrintStream类对象。
对于文本方式流对象,可以采用InputStreamReader和OuputStreamWriter、PrintWirter等处理。
代码如下:
PrintStream os = new PrintStream( new BufferedOutputStream( socket.getOutputStream() ) );
DataInputStream dis = new DataInputStream( socket.getInputStream() );
PrintWirter pw = new PrintWirter( socket.getOutputStream(), true );
BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream() ) );

5.关闭Socket和流。
每一个Socket对象的存在都会占用一定的资源,在Socket对象使用完毕时,要时期关闭,关闭Socket可以调用Socket的close()方法。在关闭Socket之前,应将与Socket相关的所有输入(出)流
全部关闭,以释放所有资源。
关闭顺序为:与Socket相关的所有输入/输出应首先关闭,然后再关闭Socket。

☆ Android Socket编程:
创建服务器的步骤:
1.指定端口实例化一个ServerSocket。
2.调用ServerSocket的accept()以在等待连接期间造成阻塞。
3.获取位于该底层Socket的流以进行读写操作。
4.将数据封装成流。
5.对Scoket进行读写。
6.关闭打开流。
注意:不要在关闭Writer之前关闭Reader。
客户端实现步骤:
1.通过IP地址和端口实例化Socket,请求连接服务器。
2.获取Socket上的流以进行读写。
3.把流包装进BufferedReader/PrintWriter的实例。
4.对Socket进行读写。
5.关闭打开的流。

原创粉丝点击