Java 代理使用及代理原理

今天再测试Socket编程时,无法连接外网。公司用的是Http的代理。上网搜索也没看太懂,所以花了大量时间来学习。看了HTTP和TCP协议的关系好,才有所明白。现在能通过Socket使用HTTP代理了,结果很简单,过程却好难。

1. 先简要说说HTTP和TCP(具体内容自行Google,资料很多很全),这里就讲讲要点:

HTTP:是应用层协议,是基于传输层协议的。

TCP: 是传输层协议,是基于网络层协议的。

IP: 是网络层协议。

一个TCP的连接要进行三次握手(就像转户口一样,不详说),HTTP只是一个应用协议,也就是相当于一个自定义协议,即其没有对底层的传输方式进行干涉,只是对数据内容格式进行了定义。打个比方,别人说“SB”(你的名字),你回答“是”,仅仅是内容格式,没有改变声音的传输方式(通过声波传送<网络硬件介质>,通过双方都能听懂的语言<TCP/IP>)。同理,FTP, Telnet也是一种应用层协议,打个比方对于FTP,别人说“SB",你回答“哎”,只是格式内容不同而已。

2. 认识到以上之后,我们再说说HTTP代理,从上可以理解,HTTP代理服务器就是这样一台机器:你把所有的HTTP请求(不管是想请求百度还是Google)都发到这个HTTP代理服务器,然后这个HTTP代理服务器请求你要访问的最终地址,把响应回传给你。这里还要注意它代理的是HTTP协议,而HTTP又是基于TCP的,也就是说这个服务器代理的是指定HTTP内容格式的TCP连接。再说下去也没意思了,看以下代码:

Java代码  

  1. //以下地址是代理服务器的地址
  2. Socket socket = new Socket("10.1.2.188", 80);
  3. //写与的内容就是遵循HTTP请求协议格式的内容,请求百度
  4. socket.getOutputStream().write(new String("GET http://www.baidu.com/ HTTP/1.1\r\n\r\n").getBytes());
  5. byte[] bs = new byte[1024];
  6. InputStream is = socket.getInputStream();
  7. int i;
  8. while ((i = is.read(bs)) > 0) {
  9. System.out.println(new String(bs, 0, i));
  10. }
  11. is.close();

当然在Java中,有Proxy代理上网的使用,此时使用URL(HTTP)就不涉及Socket(TCP)了,看如下代码

Java代码  

  1. //设置代理
  2. System.setProperty("http.proxySet", "true");
  3. System.setProperty("http.proxyHost", "10.1.2.188");
  4. System.setProperty("http.proxyPort", "80");
  5. //直接访问目的地址
  6. URL url = new URL("http://www.baidu.com");
  7. URLConnection con = url.openConnection();
  8. InputStreamReader isr = new InputStreamReader(con.getInputStream());
  9. char[] cs = new char[1024];
  10. int i = 0;
  11. while ((i = isr.read(cs)) > 0) {
  12. System.out.println(new String(cs, 0, i));
  13. }
  14. isr.close();

最后总结一下:

在使用HTTP代理的环境中,

如果使用Socket(TCP)连接外网,则直接连接代理服务器,然后在发送的HTTP请求中指明要转发到的外网网址。

如果使用URL(HTTP)连接外网,则需要设置HTTP代理参数或使用Proxy。

OK,明白以后可以随意使用了,看以下代码,使用NIO的Socket通过HTTP代理访问外网的例子:

Java代码  

  1. SocketChannel sc = SocketChannel.open(new InetSocketAddress("10.1.2.188", 80));
  2. sc.write(Charset.forName("utf8").encode("GET http://www.baidu.com/ HTTP/1.1\r\n\r\n"));
  3. ByteBuffer buffer = ByteBuffer.allocate(1024);
  4. while (sc.read(buffer) != -1) {
  5. buffer.flip();
  6. System.out.println(Charset.forName("utf8").decode(buffer));
  7. buffer.clear();
  8. }
  9. sc.close();

《《以下是从摘自他人的博客》》:http://hi.baidu.com/splike/blog/item/ed2191d7c94360d1a144dfe3.html

Java Socket编程中加入代理

2010-06-02 11:12


有些时候我们的网络不能直接连接到外网, 需要使用http或是https或是socket代理来连接到外网, 这里是java使用代理连接到外网的一些方法,:方法一使用系统属性来完成代理设置, 这种方法比较简单, 但是不能对单独的连接来设置代理:

public static void main(String[] args) {

Properties prop = System.getProperties();

// 设置http访问要使用的代理服务器的地址

prop.setProperty("http.proxyHost", "192.168.0.254");

// 设置http访问要使用的代理服务器的端口

prop.setProperty("http.proxyPort", "8080");

// 设置不需要通过代理服务器访问的主机,可以使用*通配符,多个地址用|分隔

prop.setProperty("http.nonProxyHosts", "localhost|192.168.0.*");

// 设置安全访问使用的代理服务器地址与端口

// 它没有https.nonProxyHosts属性,它按照http.nonProxyHosts 中设置的规则访问

prop.setProperty("https.proxyHost", "192.168.0.254");

prop.setProperty("https.proxyPort", "443");

// 使用ftp代理服务器的主机、端口以及不需要使用ftp代理服务器的主机

prop.setProperty("ftp.proxyHost", "192.168.0.254");

prop.setProperty("ftp.proxyPort", "2121");

prop.setProperty("ftp.nonProxyHosts", "localhost|192.168.0.*");

// socks代理服务器的地址与端口

prop.setProperty("socksProxyHost", "192.168.0.254");

prop.setProperty("socksProxyPort", "8000");

// 设置登陆到代理服务器的用户名和密码

Authenticator.setDefault(new MyAuthenticator("userName", "Password"));

}

static class MyAuthenticator extends Authenticator {

private String user = "";

private String password = "";

public MyAuthenticator(String user, String password) {

this.user = user;

this.password = password;

}

protected PasswordAuthentication getPasswordAuthentication() {

returnnew PasswordAuthentication(user, password.toCharArray());

}

}

方法二使用Proxy来对每个连接实现代理, 这种方法只能在jdk 1.5以上的版本使用(包含jdk1.5), 优点是可以单独的设置每个连接的代理, 缺点是设置比较麻烦:

public static void main(String[] args) {

try {

URL url = new URL("http://www.baidu.com");

// 创建代理服务器

InetSocketAddress addr = new InetSocketAddress("192.168.0.254",

8080);

// Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr); // Socket 代理

Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); // http 代理

// 如果我们知道代理server的名字, 可以直接使用

// 结束

URLConnection conn = url.openConnection(proxy);

InputStream in = conn.getInputStream();

// InputStream in = url.openStream();

String s = IOUtils.toString(in);

System.out.println(s);

catch (Exception e) {

e.printStackTrace();

}

}

时间: 2024-08-08 18:43:08

Java 代理使用及代理原理的相关文章

Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理

JDK动态代理的实现及原理 作者:二青 邮箱:[email protected]     微博:http://weibo.com/xtfggef 动态代理,听上去很高大上的技术,在Java里应用广泛,尤其是在Hibernate和Spring这两种框架里,在AOP,权限控制,事务管理等方面都有动态代理的实现.JDK本身有实现动态代理技术,但是略有限制,即被代理的类必须实现某个接口,否则无法使用JDK自带的动态代理,因此,如果不满足条件,就只能使用另一种更加灵活,功能更加强大的动态代理技术-- CG

Java中的静态代理、通用动态代理类以及原理剖析

代理模式和静态代理 在开发中,代理模式是常用的模式之一,一般来说我们使用的代理模式基本上都是静态代理,实现模式大致如下 : 我们以网络代理为例,简单演示一下静态代理的实现 : // 网络接口 interface Network { public void surfTheInternet(); public void gotoFacebook(); } // 普通网络 class CommonNetwork implements Network { @Override public void su

java反射与动态代理

Java反射与动态代理 Java反射机制可以动态地获取类的结构,动态地调用对象的方法,是java语言一个动态化的机制.java动态代理可以在不改变被调用对象源码的前提下,在被调用方法前后增加自己的操作,极大地降低了模块之间的耦合性.这些都是java的基础知识,要想成为一名合格的程序猿,必须掌握! Java反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为

Java的三种代理模式简述

本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展. 比如有个歌手对象叫Singer,这个对象有一个唱歌方法叫sing(). 1 public class Singer{ 2 public void sing(){ 3 System.out.println("唱一首歌"); 4 } 5 } 假如你希望,通过你的某种

Java静态代理与动态代理模式的实现

前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总没有时间见面,他也没办法.后来,房东想了一个办法,他找到了一个人代替自己和小王洽谈,房东本人不用出面,他只要把他的对房客的要求告诉他找的那个人,那个人和你商量就可以了,这样就可以完成租房这件事了.这种现实场景比比皆是,所呈现出来的其实就是代理模式的原型的一种.我们把焦点转向编程,你是否在编程中经常遇见这样一个问题,对于访问某个对象,我们希望给它的方法前加入一

java静态代理与动态代理简单分析

原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理,静态代理是在编译时就将接口.实现类.代理类一股脑儿全部手动完成,但如果我们需要很多的代理,每一个都这么手动的去创建实属浪费时间,而且会有大量的重复代码,此时我们就可以采用动态代理,动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能. 其实方法直接调用就可以完成功能,为什么

Java中的动态代理以及Proxy类的偷瞄

动态代理机制 所谓动态代理,即通过代理类Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. Java动态代理类位于Java.lang.reflect包下,主要涉及到两个类. (1)接口InvocationHandler:该接口中仅定义了一个方法. Object invoke(Object obj, Method method, Object[] args); 在实际使用时,第一个参数obj一般指代理类,method是被代理的方法,args为该方法

java 静态代理 JDK动态代理 Cglib动态代理

下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失.银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能. 静态代理 使用静态代理解决上面的问题. 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,

(转)Java动态代理与CGLib代理

本文通过spring aop的代理实现简述了java动态代理和cglib的区别,有助于理解java的代理模式 转载自:http://www.iteye.com/topic/182654 Java代码 <br>public class UserDAOImpl{ <br><br>    public void save() { <br>        // TODO Auto-generated method stub <br>        Sys

深入解析Java设计模式之动态代理

深入解析Java设计模式之动态代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替"实际"对象的对象.这些操作通常涉及与"实际"对象的通信,因此代理通常充当着中间人的角色,下面是一个用来展示动态代理结构的简单示例: /** 普通(非动态)代理示例: */ interface Interface { void doSomething(); void somethingElse(String arg); } class RealObject