UrlConnection连接和Socket连接的区别
关于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()方法内的代码。
?
?
- String packageList = AccessController.doPrivileged(new PriviAction<String>(
- "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 部分源码:
- public PriviAction(String property) {
- action = GET_SYSTEM_PROPERTY;
- arg1 = property;
- }
- public T run() {
- switch (action) {
- case GET_SYSTEM_PROPERTY:
- return (T)System.getProperty((String) arg1, (String) arg2);
- case GET_SECURITY_PROPERTY:
- return (T)Security.getProperty((String) arg1);
- case GET_SECURITY_POLICY:
- return (T)Policy.getPolicy();
- case SET_ACCESSIBLE:
- ((AccessibleObject) arg1).setAccessible(true);
- }
- return null;
- }
- PriviAction<T> 实现了 java.security.PrivilegedAction<T>接口,会执行run()方法。
- 由action = GET_SYSTEM_PROPERTY;可知会执行代码:
- (T)System.getProperty((String) arg1, (String) arg2);
- System.getProperty方法调用成员变量Properties props的getProperty(key, def)方法;
- 由于并未设置任何Properties,此处会返回默认值def。def的值是null。
- 因此会继续执行下面的代码:
- String className = "org.apache.harmony.luni.internal.net.www.protocol." + protocol
- + ".Handler";
- try {
- strmHandler = (URLStreamHandler) Class.forName(className)
- .newInstance();
- } catch (IllegalAccessException e) {
- } catch (InstantiationException e) {
- } catch (ClassNotFoundException e) {
- }
- 此时protocol是http协议,从而根据协议 (protocol) 获得协议 URLStreamHandler 对象。
- 所以此时通过反射机制创建org.apache.harmony.luni.internal.net.www.protocol.http.Handler类的实例。
- 此时回到上面提到的 strmHandler.openConnection(this);
将调用下面的Handler类的实例的openConnection(URL u)方法。
- protected URLConnection openConnection(URL u) throws IOException {
- return new HttpURLConnectionImpl(u, getDefaultPort());
- }
- ected URLConnection openConnection(URL u, Proxy proxy)
- throws IOException {
- if (null == u || null == proxy) {
- throw new IllegalArgumentException(Messages.getString("luni.1B"));
- }
- return new HttpURLConnectionImpl(u, getDefaultPort(), proxy);
- }
此时会创建HttpURLConnectionImpl对象。HttpURLConnectionImpl是java.net.HttpURLConnection的子类。 该类有个成员变量
HttpConnection connection;这才是我们要找的,该类对Socket进行了封装。
HttpConnection 部分源码如下:
private Socket socket;
- private SSLSocket sslSocket;
- private InputStream inputStream;
- private OutputStream outputStream;
- private InputStream sslInputStream;
- private OutputStream sslOutputStream;
- private HttpConfiguration config;
- public HttpConnection(HttpConfiguration config, int connectTimeout) throws IOException {
- this.config = config;
- String hostName = config.getHostName();
- int hostPort = config.getHostPort();
- Proxy proxy = config.getProxy();
- if(proxy == null || proxy.type() == Proxy.Type.HTTP) {
- socket = new Socket();
- } else {
- socket = new Socket(proxy);
- }
- socket.connect(new InetSocketAddress(hostName, hostPort), connectTimeout);
- }
- 现在UrlConnection连接和Socket连接的区别应该十分清楚了吧。
- 使用UrlConnection比直接使用Socket要简单的多,不用关心状态和线程治理。
- UrlConnection基于Http协议,只是进行了封装,添加了一些额外规则(如头信息),本质上也是建立TCP连接,利用Socket
- 实现连接和传输数据的,不过我们一般每次请求完数据后都会实现finally方法,在该方法里封闭连接。
四周是相关类的源码。
可以往这个链接地址查找更多类的源码:
http://www.docjar.com/projects/apache-harmony-6.0-src-r917296-snapshot-code.html
UrlConnection连接和Socket连接的区别的更多相关文章
- TCP连接、Http连接与Socket连接
1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...
- 比较 http连接 vs socket连接
http连接 :短连接,客户端,服务器三次握手建立连接,服务器响应返回信息,连接关闭,一次性的socket连接:长连接,客户端,服务器三次握手建立连接不中断(通过ip地址端口号定位进程)及时通讯,客户 ...
- 轮询、长轮询、长连接、socket连接、WebSocket
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源.(而每一次的 HTTP 请求和应答 ...
- Http和Socket连接区别
相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Socket连接,先要明白TCP连接.手机能够使用联 ...
- Http、tcp、Socket连接区别
转自Http.tcp.Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Sock ...
- Http和Socket连接的区别
Http和Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Socket连接,先 ...
- socket连接和http连接的区别
socket连接和http连接的区别 HTTP协议:简单对象访问协议,对应于应用层 ,HTTP协议是基于TCP连接的 tcp协议: 对应于传输层 ip协议: 对应于网络层 TCP/IP ...
- 转 Cocos网络篇[3.2](3) ——Socket连接(1)
Cocos网络篇[3.2](3) ——Socket连接(1) 2015-03-05 22:24:13 标签:network http socket cocos [唠叨] 在客户端游戏开发中,使用HTT ...
- Http和Socket连接
转自http://hi.baidu.com/%D2%B9%D1%A9%B3%E6/blog/item/d6a72d2bbf467cf2e7cd406d.html 相信不少初学手机联网开发的朋友都想知道 ...
随机推荐
- gunzip 和 unzip 解压文件到指定的目录
Linux 常用的压缩命令有 gzip 和 zip,两种压缩包的结尾不同:zip 压缩的后文件是 *.zip ,而 gzip 压缩后的文件 *.gz 相应的解压缩命令则是 gunzip 和 unzi ...
- Android Edittext点击全选输入框内容
- matlab绘制二维图形
常用的二维图形命令: plot:绘制二维图形 loglog:用全对数坐标绘图 semilogx:用半对数坐标(X)绘图 semilogy:用半对数坐标(Y)绘图 fill:绘制二维多边填充图形 pol ...
- 报这个错 unrecognized selector sent to instance
1.给一个对象赋空值: 2.调不存在的方法:3.数据类型不对.
- 【转】十分详细的xStream解析
转自博文:http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html xStream框架 xStream可以轻易的将Java对象和xml文 ...
- Android响应式界面开发要点
现在很多项目需要到达同一个Apk既可以在Phone上跑也尅在tablet上跑,即界面要适应不同尺寸和类型的需要而自动调整.这个即为响应式设计.在web开发商响应式设计已经是个常谈的内容了,而对于and ...
- Java server数据之(4):Redis鸟瞰
Redis简介 Redis是NoSQL数据库中的一种,属于key-value键值对这一个子类别. 它常被称作是一款数据结构服务器(data structure server). Redis中的数据结构 ...
- [BZOJ 1486][HNOI2009]最小圈(二分答案+dfs写的spfa判负环)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1486 分析:容易想到先二分答案x,然后把所有边的权值-x,那么如果图中存在权值和为0的 ...
- android之读取SD卡状态
package xidian.dy.com.chujia; import android.os.Build; import android.os.Environment; import android ...
- 一头扎进EasyUI
惯例广告一发,对于初学真,真的很有用www.java1234.com,去试试吧! 一头扎进EasyUI第1讲 .加载库文件和样式 <link rel="stylesheet" ...