[Android] HttpURLConnection & HttpClient & Socket

 

 

Android的三种网络联接方式
1、标准Java接口:java.net.*提供相关的类
//定义地址
URL url = new URL("http://www.google.com");
//打开连接
HttpURLConnection http = (HttpURLConnection) url.openConnection();

2、Apache接口:android.net.http.*
//DefaultHttpClient表示默认属性
HttpClient httpClient = new DefaultHttpClient();
//HttpGet实例
HttpGet get = new HttpGet("http://www.google.com");
HttpResponse rp = httpClient.execute(get);
其中post的方式请求步骤比较复杂

3、Android接口:android.net.*
//IP地址
InetAddress inetAddress = InetAddress.getByName("192.168.1.1");
//端口
Socket client = new Socket(inetAddress,61203,true);
//取得数据
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();

Android网络连接之HttpURLConnection和HttpClient

转 http://www.cnblogs.com/devinzhang/archive/2012/01/17/2325092.html

1.概念      

      HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:HttpURLConnection。但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。

      除此之外,在Android中,androidSDK中集成了Apache的HttpClient模块,用来提供高效的、最新的、功能丰富的支持 HTTP 协议工具包,并且它支持 HTTP 协议最新的版本和建议。使用HttpClient可以快速开发出功能强大的Http程序。

2.区别

HttpClient是个很不错的开源框架,封装了访问http的请求头,参数,内容体,响应等等,

HttpURLConnection是java的标准类,什么都没封装,用起来太原始,不方便,比如重访问的自定义,以及一些高级功能等。

 

URLConnection

HTTPClient

Proxies and SOCKS

Full support in Netscape browser, appletviewer, and applications (SOCKS: Version 4 only); no additional limitations from security policies.

Full support (SOCKS: Version 4 and 5); limited in applets however by security policies; in Netscape can't pick up the settings from the browser.

Authorization

Full support for Basic Authorization in Netscape (can use info given by the user for normal accesses outside of the applet); no support in appletviewer or applications.

Full support everywhere; however cannot access previously given info from Netscape, thereby possibly requesting the user to enter info (s)he has already given for a previous access. Also, you can add/implement additional authentication mechanisms yourself.

Methods

Only has GET and POST.

Has HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS, plus any arbitrary method.

Headers

Currently you can only set any request headers if you are doing a POST under Netscape; for GETs and the JDK you can't set any headers. 
Under Netscape 3.0 you can read headers only if the resource was returned with a Content-length header; if no Content-length header was returned, or under previous versions of Netscape, or using the JDK no headers can be read.

Allows any arbitrary headers to be sent and received.

Automatic Redirection Handling

Yes.

Yes (as allowed by the HTTP/1.1 spec).

Persistent Connections

No support currently in JDK; under Netscape uses HTTP/1.0 Keep-Alive's.

Supports HTTP/1.0 Keep-Alive's and HTTP/1.1 persistence.

Pipelining of Requests

No.

Yes.

Can handle protocols other than HTTP

Theoretically; however only http is currently implemented.

No.

Can do HTTP over SSL (https)

Under Netscape, yes. Using Appletviewer or in an application, no.

No (not yet).

Source code available

No.

Yes.

3.案例

URLConnection

复制代码
    String urlAddress = "http://192.168.1.102:8080/AndroidServer/login.do";  
URL url;
HttpURLConnection uRLConnection;
public UrlConnectionToServer(){

}
    //向服务器发送get请求
public String doGet(String username,String password){
String getUrl = urlAddress + "?username="+username+"&password="+password;
try {
url = new URL(getUrl);
uRLConnection = (HttpURLConnection)url.openConnection();
InputStream is = uRLConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();
uRLConnection.disconnect();
return response;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
 
    //向服务器发送post请求
public String doPost(String username,String password){
try {
url = new URL(urlAddress);
uRLConnection = (HttpURLConnection)url.openConnection();
uRLConnection.setDoInput(true);
uRLConnection.setDoOutput(true);
uRLConnection.setRequestMethod("POST");
uRLConnection.setUseCaches(false);
uRLConnection.setInstanceFollowRedirects(false);
uRLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
uRLConnection.connect();

DataOutputStream out = new DataOutputStream(uRLConnection.getOutputStream());
String content = "username="+username+"&password="+password;
out.writeBytes(content);
out.flush();
out.close();

InputStream is = uRLConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();
uRLConnection.disconnect();
return response;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
复制代码

HTTPClient

复制代码
String urlAddress = "http://192.168.1.102:8080/qualityserver/login.do";  
public HttpClientServer(){

}

public String doGet(String username,String password){
String getUrl = urlAddress + "?username="+username+"&password="+password;
HttpGet httpGet = new HttpGet(getUrl);
HttpParams hp = httpGet.getParams();
hp.getParameter("true");
//hp.
//httpGet.setp
HttpClient hc = new DefaultHttpClient();
try {
HttpResponse ht = hc.execute(httpGet);
if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity he = ht.getEntity();
InputStream is = he.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();

//String str = EntityUtils.toString(he);
System.out.println("========="+response);
return response;
}else{
return "error";
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
}

public String doPost(String username,String password){
//String getUrl = urlAddress + "?username="+username+"&password="+password;
HttpPost httpPost = new HttpPost(urlAddress);
List params = new ArrayList();
NameValuePair pair1 = new BasicNameValuePair("username", username);
NameValuePair pair2 = new BasicNameValuePair("password", password);
params.add(pair1);
params.add(pair2);

HttpEntity he;
try {
he = new UrlEncodedFormEntity(params, "gbk");
httpPost.setEntity(he);

} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

HttpClient hc = new DefaultHttpClient();
try {
HttpResponse ht = hc.execute(httpPost);
//连接成功
if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity het = ht.getEntity();
InputStream is = het.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();

//String str = EntityUtils.toString(he);
System.out.println("=========&&"+response);
return response;
}else{
return "error";
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
}
复制代码

servlet端json转化: 

复制代码
        resp.setContentType("text/json");  
resp.setCharacterEncoding("UTF-8");
toDo = new ToDo();
List<UserBean> list = new ArrayList<UserBean>();
list = toDo.queryUsers(mySession);
String body;

//设定JSON
JSONArray array = new JSONArray();
for(UserBean bean : list)
{
JSONObject obj = new JSONObject();
try
{
obj.put("username", bean.getUserName());
obj.put("password", bean.getPassWord());
}catch(Exception e){}
array.add(obj);
}
pw.write(array.toString());
System.out.println(array.toString());
复制代码

android端接收:

复制代码
String urlAddress = "http://192.168.1.102:8080/qualityserver/result.do";  
String body =
getContent(urlAddress);
JSONArray array = new JSONArray(body);
for(int i=0;i<array.length();i++)
{
obj = array.getJSONObject(i);
sb.append("用户名:").append(obj.getString("username")).append("\t");
sb.append("密码:").append(obj.getString("password")).append("\n");

HashMap<String, Object> map = new HashMap<String, Object>();
try {
userName = obj.getString("username");
passWord = obj.getString("password");
} catch (JSONException e) {
e.printStackTrace();
}
map.put("username", userName);
map.put("password", passWord);
listItem.add(map);

}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if(sb!=null)
{
showResult.setText("用户名和密码信息:");
showResult.setTextSize(20);
} else
extracted();

//设置adapter
SimpleAdapter simple = new SimpleAdapter(this,listItem,
android.R.layout.simple_list_item_2,
new String[]{"username","password"},
new int[]{android.R.id.text1,android.R.id.text2});
listResult.setAdapter(simple);

listResult.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int positionId = (int) (id+1);
Toast.makeText(MainActivity.this, "ID:"+positionId, Toast.LENGTH_LONG).show();

}
});
}
private void extracted() {
showResult.setText("没有有效的数据!");
}
//和服务器连接
private String getContent(String url)throws Exception{
StringBuilder sb = new StringBuilder();
HttpClient client =new DefaultHttpClient();
HttpParams httpParams =client.getParams();

HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpResponse response = client.execute(new HttpGet(url));
HttpEntity entity =response.getEntity();

if(entity !=null){
BufferedReader reader = new BufferedReader(new InputStreamReader
(entity.getContent(),"UTF-8"),8192);
String line =null;
while ((line= reader.readLine())!=null){
sb.append(line +"\n");
}
reader.close();
}
return sb.toString();
}

 

HttpURLConnection是一种重要访 HTTP 资源HttpURLConnection 类具访,可以取代HttpGetHttpPost。使用HttpUrlConnection 访HTTP资源可以使用如

1使用java.net.URL封装HTTP资源url使用openConnection方法HttpUrlConnection 对象代码下:

URL url = new URL("http://www.blogjava.net/nokiaguy/archive/2009/12/14/305890.html");

HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

2.设方法GETPOST等,代码下:

httpURLConnection.setRequestMethod("POST");

注意的是,setRequestMethod方法必须GETPOST等。

3.设输入输出及。如果要下 HTTP资源或向服务端上传数需要使用如下代码

// HTTP资源需要setDoInput方法的设为true
httpURLConnection.setDoInput(true);
//
上传数据,需要setDoOutput方法的设为true
httpURLConnection.setDoOutput(true);

HttpURLConnection更多的如,使用下面代码可以HttpURLConnection使用缓存

httpURLConnection.setUseCaches(false);

4.设HTTP。在很多情况据实际情况设一些HTTP下面的代码CharsetUTF-8

httpURLConnection.setRequestProperty("Charset", "UTF-8");

5输入 HTTP 资源读写,也就是通 InputStream 和OutputStream读取下面代码InputStream对象OutputStream对象

InputStream is = httpURLConnection.getInputStream();
OutputStream os = httpURLConnection.getOutputStream();

于是读取还是需要据具情况而定

6.关闭输入输。虽然关闭输入输流并不的,在应用程序输入输会自关闭,但关闭输入输是一习惯关闭输入输代码下:

is.close();
os.close();

 

转http://www.eoeandroid.com/thread-314728-1-1.html

最近在研究Volley框架的源码,发现它在HTTP请求的使用上比较有意思,在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。我也比较好奇这么使用的原因,于是专门找到了一位Google的工程师写的一篇博客,文中对 HttpURLConnection和HttpClient进行了对比,下面我就给大家简要地翻译一下。
原文地址:http://android-developers.blogspot.com/2011/09/androids-http-clients.html
大多数的Android应用程序都会使用HTTP协议来发送和接收网络数据,而Android中主要提供了两种方式来进行HTTP操 作,HttpURLConnection和HttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、 以及连接池等功能。
HttpClientDefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。
但同时也由于HttpClient的API数量过多,使得我们很难在不破坏兼容性的情况下对它进行升级和扩展,所以目前Android团队在提升和优化HttpClient方面的工作态度并不积极。
HttpURLConnectionHttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnection的API提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。
不过在Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:
[java] view plaincopy

  • private void disableConnectionReuseIfNecessary() {  
  •     // 这是一个2.2版本之前的bug  
  •     if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {  
  •         System.setProperty("http.keepAlive", "false");  
  •     }  
  • }  


在Android 2.3版本的时候,我们加入了更加透明化的响应压缩。HttpURLConnection会自动在每个发出的请求中加入如下消息头,并处理相应的返回结果:Accept-Encoding: gzip

配置你的Web服务器来支持对客户端的响应进行压缩的功能,从而可以在这一改进上获取到最大的好处。如果在压缩响应的时候出现了问题,这篇文档会告诉你如何禁用掉这个功能。
但是如果启动了响应压缩的功能,HTTP响应头里的Content-Length就会代表着压缩后的长度,这时再使用 getContentLength()方法来取出解压后的数据就是错误的了。正确的做法应该是一直调用InputStream.read()方法来读取响 应数据,一直到出现-1为止。
我们在Android 2.3版本中还增加了一些HTTPS方面的改进,现在HttpsURLConnection会使用SNI(Server Name Indication)的方式进行连接,使得多个HTTPS主机可以共享同一个IP地址。除此之外,还增加了一些压缩和会话的机制。如果连接失败,它会自 动去尝试重新进行连接。这使得HttpsURLConnection可以在不破坏老版本兼容性的前提下,更加高效地连接最新的服务器。
在Android 4.0版本中,我们又添加了一些响应的缓存机制。当缓存被安装后(调用HttpResponseCache的install()方法),所有的HTTP请求都会满足以下三种情况:
所有的缓存响应都由本地存储来提供。因为没有必要去发起任务的网络连接请求,所有的响应都可以立刻获取到。
视情况而定的缓存响应必须要有服务器来进行更新检查。比如说客户端发起了一条类似于 “如果/foo.png这张图片发生了改变,就将它发送给我” 这样的请求,服务器需要将更新后的数据进行返回,或者返回一个304 Not Modified状态。如果请求的内容没有发生,客户端就不会下载任何数据。
没有缓存的响应都是由服务器直接提供的。这部分响应会在稍后存储到响应缓存中。
由于这个功能是在4.0之后的版本才有的,通常我们就可以使用反射的方式来启动响应缓存功能。下面的示例代码展示了如何在Android 4.0及以后的版本中去启用响应缓存的功能,同时还不会影响到之前的版本:
[java] view plaincopy

  • private void enableHttpResponseCache() {  
  •     try {  
  •         long httpCacheSize = 10 * 1024 * 1024; // 10 MiB  
  •         File httpCacheDir = new File(getCacheDir(), "http");  
  •         Class.forName("android.net.http.HttpResponseCache")  
  •             .getMethod("install", File.class, long.class)  
  •             .invoke(null, httpCacheDir, httpCacheSize);  
  •     } catch (Exception httpResponseCacheNotAvailable) {  
  •     }  
  • }  


你也应该同时配置一下你的Web服务器,在HTTP响应上加入缓存的消息头。哪一种才是最好的?在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。
而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可 以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在 以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。

 

客户端Socket连接服务器与服务器交互代码

Socket socket = new Socket("192.168.17.100", 8080);    或者 Socket socket = new Socket(); socket.connect(new InetSocketAddress("192.168.18.100", 8080));


OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os)
BufferedWriter bw = new BufferedWriter(osw);

 

// 向服务器写数据
bw.write("hello world\r\n\r\n");
bw.flush();

InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String s = "";
//
从服务器读数据
while((s = br.readLine()) != null)
  Log.d("line", s);


//
下面的代码关闭输入输出流以及Socket连接
os.close();
is.close();
socket.close();

 

服务端Socket:

ServerSocket serverSocket = new ServerSocket(1234); // ServerSocket serverSocket = new ServerSocket(1234, 100);  100为请求队列的长度

// 处理其他任务的代码
while(true)
{
  Socket socket = serverSocket.accept(); //
等待接收客户端请求
  //
处理其他任务的代码
  new ThreadClass(socket).start(); //
创建并运行处理客户端请求的线程
}

 

 

 

上传件的HTTP分为4分:

1. 分字符--和一意字符串。使用浏览上传件一般为-----------------符为一行。

2. 上传件的些信息包括请、上传类型,但并不于此,Content-Disposition: form-data; name="file"; filename="abc.jpg"

3. 上传件的形式

4. 文上传个符没有出来。当上传的件是最后一个,在 HTTP会出现这个符字符串是在符后面字符如,-----------------------------------218813199810322--就是一

 

Android SDK支持访HTTPS资源代码下:

 

// 所有host
HostnameVerifier hostnameVerifier =
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));

//
像访问HTTP资源使用httpClient httpPost
DefaultHttpClient client = new DefaultHttpClient();
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
HttpPost httpPost = new HttpPost("https://www.myhttps.com");

// 下面的代码访问HTTP资源完全

...

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2014-06-17 13:36  【雨歌】  阅读(1663)  评论(0编辑  收藏  举报