Java socket - 使用代理服务器
为什么使用代理服务器不需要多说了。
使用Proxy
Java提供了Proxy类实现使用代理进行通信。
Proxy类的构造器Proxy(Proxy.Type type, SocketAddress sa)。其中type表示代理类型,代理类型有三种:DIRECT(表示不使用代理)、HTTP(表示使用高级协议代理比如http或FTP)、SOCKETS(表示使用sockets代理)。sa表示代理地址。
一旦创建Proxy对象后,程序就可以在使用URLConnection打开连接时,或者创建用socket连接时,传入一个Proxy对象作为本次连接使用的代理服务器。
其中URL提供了一个URLConnection openConnection(Proxy proxy); Socket则提供了一个Socket(Proxy proxy)构造器。
使用URL的openConnection为例:
public static void httpProxy() throws IOException {
// 代理对象
Proxy proxy = new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(IP, PORT)); // 需要访问的地址
String urlStr = "http://www.zhyea.com";
// 创建连接
URL url = new URL(urlStr);
URLConnection conn = url.openConnection(proxy);
// 输出访问结果
try {
Scanner scan = new Scanner(conn.getInputStream());
StringBuilder builder = new StringBuilder();
while (scan.hasNextLine()) {
builder.append(scan.nextLine()).append(StringUtils.NEWLINE);
}
System.out.println(builder.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
使用ProxySelector
先不多做解释,直接上代码:
public static void httpProxy() throws IOException { ProxySelector.setDefault(new ProxySelector() { @Override
public List<Proxy> select(URI uri) {
List<Proxy> list = new ArrayList<Proxy>();
list.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
"10.10.8.84", 8080)));
return list;
} @Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
System.out.println("连接代理失败!");
} });
// 需要访问的地址
String urlStr = "http://www.baidu.com";
// 创建连接
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
// 输出访问结果
try {
Scanner scan = new Scanner(conn.getInputStream());
StringBuilder builder = new StringBuilder();
while (scan.hasNextLine()) {
builder.append(scan.nextLine()).append(StringUtils.NEWLINE);
}
System.out.println(builder.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
如上的代码并没有显式的指定代理服务器,但是在我提供一个无效的代理IP的时候,控制台输出了“连接代理失败”的字样。说明程序使用了我提供的代理。
ProxySelector是一个抽象类,它提供了两个方法select、connectFailed需要用户自己实现:
- select:返回代理服务器列表(据测试会默认使用第一个代理);
- connectFailed:连接代理失败时的处理方法。
Java为ProxySelector提供了一个实现类DefaultProxySelector,且将之注册为默认的代理实现类,一般不需要显式实现,需要时可以通过ProxySelector.getDefault()来调用。简单说下DefaultProxySelector对ProxySelector的实现:
- select:会根据系统属性来选择使用代理服务器。关于代理服务器的系统属性有如下三个http.proxyHost,http.proxyPort,http.nonProxyHosts(具体使用方法参看实例);
- connectFailed:连接代理失败后会尝试使用直接连接。
如下是一个实例(懒得自己写了,直接在网上找了一个):
package com.zhyea.olproxy.test; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;
import java.util.Scanner; public class ProxySelectorTest {
// 测试本地JVM的网络默认配置
public void setLocalProxy() {
Properties prop = System.getProperties();
// 设置HTTP访问要使用的代理服务器的地址
prop.setProperty("http.proxyHost", "10.10.8.84");
// 设置HTTP访问要使用的代理服务器的端口
prop.setProperty("http.proxyPort", "8080");
// 设置HTTP访问不需要通过代理服务器访问的主机,
// 可以使用*通配符,多个地址用|分隔
prop.setProperty("http.nonProxyHosts", "localhost|10.20.*");
// 设置安全HTTP访问使用的代理服务器地址与端口
// 它没有https.nonProxyHosts属性,它按照http.nonProxyHosts 中设置的规则访问
prop.setProperty("https.proxyHost", "192.168.0.96");
prop.setProperty("https.proxyPort", "443");
// 设置FTP访问的代理服务器的主机、端口以及不需要使用代理服务器的主机
prop.setProperty("ftp.proxyHost", "10.10.0.96");
prop.setProperty("ftp.proxyPort", "2121");
prop.setProperty("ftp.nonProxyHosts", "localhost|10.10.*");
// 设置socks代理服务器的地址与端口
prop.setProperty("socks.ProxyHost", "10.10.0.96");
prop.setProperty("socks.ProxyPort", "1080");
} // 清除proxy设置
public void removeLocalProxy() {
Properties prop = System.getProperties();
// 清除HTTP访问的代理服务器设置
prop.remove("http.proxyHost");
prop.remove("http.proxyPort");
prop.remove("http.nonProxyHosts");
// 清除HTTPS访问的代理服务器设置
prop.remove("https.proxyHost");
prop.remove("https.proxyPort");
// 清除FTP访问的代理服务器设置
prop.remove("ftp.proxyHost");
prop.remove("ftp.proxyPort");
prop.remove("ftp.nonProxyHosts");
// 清除SOCKS的代理服务器设置
prop.remove("socksProxyHost");
prop.remove("socksProxyPort");
} // 测试HTTP访问
public void showHttpProxy() throws MalformedURLException, IOException {
URL url = new URL("http://www.baidu.com");
// 直接打开连接,但系统会调用刚设置的HTTP代理服务器
URLConnection conn = url.openConnection(); // ①
Scanner scan = new Scanner(conn.getInputStream());
// 读取远程主机的内容
while (scan.hasNextLine()) {
System.out.println(scan.nextLine());
}
} public static void main(String[] args) throws IOException {
ProxySelectorTest test = new ProxySelectorTest();
test.setLocalProxy();
test.showHttpProxy();
test.removeLocalProxy();
}
}
这个写得很全了。
就这样。
Java socket - 使用代理服务器的更多相关文章
- JAVA通信系列一:Java Socket技术总结
本文是学习java Socket整理的资料,供参考. 1 Socket通信原理 1.1 ISO七层模型 1.2 TCP/IP五层模型 应用层相当于OSI中的会话层,表示层, ...
- JAVA Socket 编程学习笔记(二)
在上一篇中,使用了 java Socket+Tcp/IP 协议来实现应用程序或客户端--服务器间的实时双向通信,本篇中,将使用 UDP 协议来实现 Socket 的通信. 1. 关于UDP UDP协 ...
- JAVA Socket 编程学习笔记(一)
1. Socket 通信简介及模型 Java Socket 可实现客户端--服务器间的双向实时通信.java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的cli ...
- Java Socket Server的演进 (一)
最近在看一些网络服务器的设计, 本文就从起源的角度介绍一下现代网络服务器处理并发连接的思路, 例子就用java提供的API. 1.单线程同步阻塞式服务器及操作系统API 此种是最简单的socket服务 ...
- JAVA Socket超时浅析
JAVA Socket超时浅析 套接字或插座(socket)是一种软件形式的抽象,用于表达两台机器间一个连接的"终端".针对一个特定的连接,每台机器上都有一个"套接字&q ...
- Java Socket编程题库
一. 填空题 ___ IP地址____用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 统一资源定位符URL是指向互联网"资源"的指针,由4部分组成:协议 ...
- Java Socket编程(转)
Java Socket编程 对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket.服务端和客户端之间通过Socket建立连接,之后它们就可以进行通信了.首 ...
- 交通银行 Java Socket 服务启动 管理 WINDOWS 版
按照交通银行提供的无界面启动方法试验了很多次,都没有成功,所以自己动手用C# 知识写了一个. 小工具可以判断 交通银行 JAVA SOCKET 服务是否启动,并可以启动/关闭服务 主要代码如下: 判断 ...
- Java Socket 网络编程心跳设计概念
Java Socket 网络编程心跳设计概念 1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...
随机推荐
- 【IDEA】本地新建Maven项目+配置Git和GitHub+代码上传和拉取到GitHub+其他IDEA和GitHub实战
一.本地新建Maven项目并启动成功 1. 按照IDEA提供的模板,构建一个maven webapp的模板项目. 一路Next,到最后的finish.如下图. 2. 新建Tomcat,启动刚建立的项目 ...
- python中 将字符串和字典的相互转换
1.首先引入json模块 # 引入json模块 import json 2.转换 #JSON到字典转化: dictinfo = json.loads(json_str) # 输出dict类型 字典到J ...
- 第00章—IDEA
spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...
- ios cocos2d 使用 sneakyInput 插件
昨晚看了篇使用sneakyInput插件实现模拟手柄的代码,不过我加上后出现了很多问题.最后只看如何实现,没有自己动手去操作.今天终于吧问题都解决了.记录下来.也供别人参考. 首先要先加入libz.d ...
- java 统计文件注释个数
参考:https://segmentfault.com/q/1010000012636380/a-1020000012640905 题目:统计文件中//和/* */注释的个数,双引号中的不算 impo ...
- 解决ajax无法给js全局变量赋值的问题
解决ajax无法给js全局变量赋值的问题 http://blog.csdn.net/qq_26222859/article/details/51543433 在ajax中是无法给js中的全局变量赋值的 ...
- JavaEE中为什么出现中文乱码?
1.原因 客户端通过IE提交时用的默认编码是UTF-8,而当我们用Myeclipse的时候的服务端接受的时候用的是iso-8859-1 2.解决方法 服务端也用UTF-8编码 byte[] resul ...
- MB11 生鲜项目原料消耗发货功能
*&---------------------------------------------------------------------* *& 程序名: ZDQFI_925 * ...
- df: `/root/.gvfs': Permission denied
在使用oracle账户检查本地磁盘情况时,总是出现df: `/root/.gvfs': Permission denied信息提示. [oracle@rac1 ~]$ df -h Filesystem ...
- Django——请求生命周期
视图层之视图函数(views) 一个视图函数,简称视图,他可以接受Web请求,并且必须返回一个Web响应,响应内容可以是一个HTML内容,一张图片,一个404错误,一个文档等等,都可以称为web为你响 ...