UrlConnection连接和Socket连接的区别

来源:互联网 发布:win10 优化 编辑:程序博客网 时间:2024/06/06 05:48

关于UrlConnection连接和Socket连接的区别,只知道其中的原理如下:

抽象一点的说,Socket只是一个供上层调用的抽象接口,隐藏了传输层协议的细节。

urlconnection 基于Http协议,Http协议是应用层协议,对传输层Tcp协议进行了封装,是无状态协议,不需要你去考虑线程、同步、状态管理等,内部是通过socket进行连接和收发数据的,不过一般在数据传输完成之后需要关闭socket连接。

直接使用Socket进行网络通信得考虑线程管理、客户状态监控等,但是不用发送头信息等,更省流量。


并不知道我们经常使用的URLConnection 内部是怎么实现的,今天心血来潮以URL为起点来探个究竟。

以下面这段代码为出发点

URL url = new URL("http://zhoujianghai.iteye.com");

URLConnection conecttion = (URLConnection)url.openConnection();


根据java.net.URL源码,一步步进行分析,

new URL("www.javaeye.com")会调用URL(URL context, String spec, URLStreamHandler handler),

此时context和handler是null。

url.openConnection()调用的是strmHandler.openConnection(this);

而strmHandler是URLStreamHandler接口的子类的实例。

抽象类 URLStreamHandler 是所有流协议处理程序的通用超类,可以通过不同 protocol 的 URL 实例,产生 java.net.URLConnection 对象。

由于context和handler是null,所以最终根据具体的协议调用URL类中的setupStreamHandler()方法对strmHandler进行初始化。


下面分析 setupStreamHandler()方法内的代码。

 

 

Java代码  

  1. String packageList = AccessController.doPrivileged(new PriviAction<String>(  
  2.                         "java.protocol.handler.pkgs"));  

 

 

首先通过java.protocol.handler.pkgs 来设置 URLStreamHandler 实现类的包路径,SUN 的 JDK 内部实现类均是在 sun.net.www.protocol. 包下。

关于sun/net/www/protocol/http包下相关类的源码,可以访问:http://www.docjar.org/docs/api/sun/net/www/protocol/http/package-index.html


PriviAction 部分源码:

Java代码  

  1. public PriviAction(String property) {  
  2.       action = GET_SYSTEM_PROPERTY;  
  3.     arg1 = property;  
  4.     }  
  5.   
  6. public T run() {  
  7.    switch (action) {  
  8.      case GET_SYSTEM_PROPERTY:  
  9.      return (T)System.getProperty((String) arg1, (String) arg2);  
  10.     case GET_SECURITY_PROPERTY:  
  11.      return (T)Security.getProperty((String) arg1);  
  12.      case GET_SECURITY_POLICY:  
  13.      return (T)Policy.getPolicy();  
  14.      case SET_ACCESSIBLE:  
  15.      ((AccessibleObject) arg1).setAccessible(true);  
  16.      }  
  17.      return null;  
  18.      }  

 

 


PriviAction<T> 实现了 java.security.PrivilegedAction<T>接口,会执行run()方法。

由action = GET_SYSTEM_PROPERTY;可知会执行代码:

 

 

Java代码  

  1. (T)System.getProperty((String) arg1, (String) arg2);  

 

 


System.getProperty方法调用成员变量Properties props的getProperty(key, def)方法;

由于并未设置任何Properties,此处会返回默认值def。def的值是null。

因此会继续执行下面的代码:

Java代码  

  1. String className = "org.apache.harmony.luni.internal.net.www.protocol." + protocol   
  2. + ".Handler";   
  3.         try {  
  4.             strmHandler = (URLStreamHandler) Class.forName(className)  
  5.                     .newInstance();  
  6.         } catch (IllegalAccessException e) {  
  7.         } catch (InstantiationException e) {  
  8.         } catch (ClassNotFoundException e) {  
  9.         }  

 

 

此时protocol是http协议,从而根据协议 (protocol) 获得协议 URLStreamHandler 对象。

所以此时通过反射机制创建org.apache.harmony.luni.internal.net.www.protocol.http.Handler类的实例。

此时回到上面提到的 strmHandler.openConnection(this);

将调用下面的Handler类的实例的openConnection(URL u)方法。


    @Override

Java代码  

  1. protected URLConnection openConnection(URL u) throws IOException {  
  2.     return new HttpURLConnectionImpl(u, getDefaultPort());  
  3. }  
  4.   
  5.   
  6. protected URLConnection openConnection(URL var1, Proxy var2) throws IOException {
        return new HttpURLConnection(var1, var2, this);

HttpURLConnection 对象封装了 URL 类和 处理器类,

url 类 对应 请求字符串

URLStreamHandler  处理器类对应特定的请求字符串的处理,不同的请求字符串获取 inputstream 的方式不同。


 

0 0
原创粉丝点击