
从JDK15开始,Java在javanet包下提供了Proxy和ProxySelector两个类,其中Proxy代表一个代理服务器,可以在打开URLConnection连接时指定所用的Proxy实例,也可以在创建Socket连接时指定Proxy实例。而ProxySelector代表一个代理选择器,它提供了对代理服务器更加灵活的控制,它可以对>
代理服务器的功能就是代理网络用户去取得网络信息。我们使用网络浏览器直接连接其他Internet站点取得网络信息时,通常需要发送Request请求来等到响应。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取得网页数据而是向代理服务器发出请求,Request请求会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并送回给网络浏览器。而且,大部分代理服务器都具有缓冲的功能,就好像一个大的Cache,它有很大的存储空间,它不断将新取得的数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。归纳起来代理服务器主要提供如下两个功能:
突破自身IP限制,对外隐藏自身IP地址。突破IP限制包括访问国外受限站点,访问国内特定单位、团体的内部资源。
提高访问速度,代理服务器提供的缓冲功能可以避免每个用户都直接访问远程主机,从而提高客户端访问速度。
1751 直接使用Proxy创建连接
Proxy有如下一个构造器:Proxy(ProxyType type, SocketAddress sa):创建表示代理服务器的Proxy对象。而sa参数指定代理服务器的地址,其中type是该代理服务器的类型,该服务器类型有如下三种:
(1)ProxyTypeDIRECT:表示直接连接或缺少代理。
(2)ProxyType>
(3)ProxyTypeSOCKS:表示 SOCKS(V4 或 V5)代理。
一旦创建了Proxy对象之后,程序就可以在使用URLConnection打开连接时,或创建Socket连接时传入一个Proxy对象,作为本次连接所使用的代理服务器。
其中URL包含了一个URLConnection openConnection(Proxy proxy)方法,该方法使用指定的代理服务器来打开连接;而Socket则提供了一个Socket(Proxy proxy)构造器,该构造器使用指定的代理服务器创建一个没有连接的Socket对象。
下面以URLConnection为例来介绍如何在URLConnection中使用代理服务器。
程序清单:codes/17/17-5/ProxyTestjava
上面代码第一行粗体字代码创建了一个Proxy对象,第二行粗体字代码就是用Proxy对象来打开URLConnection连接。除此之外,该程序的其他地方就是对URLConnection的使用了。由此可见, JDK15提供了对代理服务器很好的支持。
1752 使用ProxySelector选择代理服务器
前面介绍的直接使用Proxy对象可以在打开URLConnection或Socket时指定代理服务器,使用这种方式需要每次打开连接都显式设置代理服务器。如果想让系统打开连接时总是具有默认的代理服务器,则可以使用javanetProxySelector,它可以它根据不同的连接使用不同的代理服务器。
系统默认的ProxySelector会检测各种系统属性和URL协议,然后决定怎样连接不同的主机。当然,程序也可以调用ProxySelector类的setDefaultI()静态方法来设置默认代理服务器,也可以调用getDefault()方法获得系统当前默认的代理服务器。
程序可以通过System类来设置系统的代理服务器属性,关于代理服务器常用的属性名有如下三个:
>
>
>
下面程序示范了通过改变系统属性来改变默认的代理服务器。
程序清单:codes/17/17-5/ ProxySelectorTestjava
上面程序中三行粗体字代码设置Java打开>
运行上面程序,将会看到程序长时间等待,因为192168096通常并不是有效的代理服务器(当然,如果读者运行的机器恰好可以使用地址为192168096的代理服务器又另当别论)。
系统提供了默认的ProxySelector子类作为代理选择器,开发者可以实现自己的代理选择器,程序可以通过继承ProxySelector来实现自己的代理选择器。继承ProxySelector需要重写两个方法:
List<Proxy> select(URI uri):实现该方法让代理选择器根据不同的URI来使用不同的代理服务器,该方法就是代理选择器管理网络连接使用代理服务器的关键。
connectFailed(URI uri, SocketAddress sa, IOException ioe):当系统通过默认的代理服务器建立连接失败后,代理选择器将会自动调用该方法。通过重写该方法可以对连接代理服务器失败的情形进行处理。
系统默认的代理服务器选择器也重写了connectFailed方法,它重写该方法的处理策略是:当系统设置的代理服务器失败时,默认代理选择器将会采用直连的方式连接远程资源,所以当运行上面程序等待了足够长时间时,程序依然可以打印出该远程资源的所有内容。
下面是我自己写的一个读取并显示txt文件的demo,希望对您有帮助。public class Client {
public static void main(String[] args) {
ClientFrame f = new ClientFrame();
}
}
import javaawtBorderLayout;
import javaawtContainer;
import javaawtDimension;
import javaawtGridLayout;
import javaawtToolkit;
import javaawteventActionEvent;
import javaawteventActionListener;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioIOException;
import javanetSocket;
import javanetUnknownHostException;
import javautilVector;
import javaxswingBorderFactory;
import javaxswingJButton;
import javaxswingJFrame;
import javaxswingJList;
import javaxswingJScrollPane;
import javaxswingJTextArea;
import javaxswingeventListSelectionEvent;
import javaxswingeventListSelectionListener;
public class ClientFrame extends JFrame implements ActionListener, ListSelectionListener{
private JList list = null;
private JButton sbtn = null;
private JButton cbtn = null;
private Vector v = null;
private JTextArea txt = null;
private Container control = null;
private Container btn = null;
private Socket client = null;
private DataInputStream reader = null;
private DataOutputStream writer = null;
public ClientFrame(){
thislist = new JList();
thislistsetBorder(BorderFactorycreateTitledBorder("文件列表"));
thislistaddListSelectionListener(this);
thissbtn = new JButton("显示");
thissbtnaddActionListener(this);
thiscbtn = new JButton("清除");
thiscbtnaddActionListener(this);
thiscontrol = new Container();
thiscontrolsetPreferredSize(new Dimension(150, 400));
thiscontrolsetLayout(new BorderLayout());
thiscontroladd(new JScrollPane(thislist),BorderLayoutCENTER);
thisbtn = new Container();
thisbtnsetLayout(new GridLayout(1,2));
btnadd(sbtn);
btnadd(cbtn);
thiscontroladd(thisbtn,BorderLayoutSOUTH);
thistxt = new JTextArea();
thistxtsetEditable(false);
thistxtsetSize(350, 400);
thissetTitle("客户端");
thissetSize(500, 400);
thissetVisible(true);
Dimension displaySize = ToolkitgetDefaultToolkit()getScreenSize();
thissetLocation((displaySizewidth - thisgetWidth()) / 2, (displaySizeheight - thisgetHeight()) / 2);
thissetLayout(new BorderLayout());
thisadd(thiscontrol,BorderLayoutWEST);
thisadd(new JScrollPane(thistxt),BorderLayoutCENTER);
thissetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);
try {
//thisclient = new Socket("1921683234",6666);
thisclient = new Socket("1921681100",6666);
thisreader = new DataInputStream(clientgetInputStream());
thiswriter = new DataOutputStream(clientgetOutputStream());
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}
public void actionPerformed(ActionEvent event){
if(eventgetSource() == sbtn){
if(v == null){
v = new Vector();
}
else{
vclear();
}
try {
writerwriteUTF("getfilelist");
writerflush();
String t = readerreadUTF();
while( t != null && !tequals("")){
vadd(t);
t = readerreadUTF();
}
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
thislistsetListData(v);
}
if(eventgetSource() == cbtn){
thistxtsetText("");
}
}
public void valueChanged(ListSelectionEvent e) {
int i = thislistgetSelectedIndex();
if (! thislistgetValueIsAdjusting() && i != -1) {
try {
writerwriteUTF("getfilecontent_" + i);
writerflush();
String tmp = readerreadUTF();
thistxtsetText(tmp);
} catch (IOException e1) {
e1printStackTrace();
}
}
}
}
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFile;
import javaioFileInputStream;
import javaioIOException;
import javaioInputStreamReader;
import javaioReader;
import javanetServerSocket;
import javanetSocket;
import javautilArrayList;
import javautilIterator;
public class Server {
static ArrayList<File> fileArray = new ArrayList<File>();
public static void main(String args[]) {
ServerSocket server = null;
Socket client = null;
String cmd = "";
try {
server = new ServerSocket(6666);
client = serveraccept();
DataInputStream reader = new DataInputStream(clientgetInputStream());
DataOutputStream writer = new DataOutputStream(clientgetOutputStream());
while(true){
cmd = readerreadUTF();
Systemoutprintln(cmd);
if(cmdequals("getfilelist")){
fileArrayclear();
//fileArray = getFile(new File("D:/tmp"));
fileArray = getFile(new File("D:/学习/教程/学习笔记"));
String fn = "";
for(int k = 0; k < fileArraysize(); k ++){
fn = fileArrayget(k)getName();
writerwriteUTF(fn);
writerflush();
}
writerwriteUTF("");
}
if(cmdstartsWith("getfilecontent_")){
int i = IntegerparseInt(cmdsplit("_")[1]);
File f = fileArrayget(i);
Reader in = new InputStreamReader(new FileInputStream(f));
int tempbyte;
String str = "";
while ((tempbyte = inread()) != -1) {
str += (char)tempbyte;
//Systemoutprintln(str);
}
inclose();
writerwriteUTF(str);
}
}
} catch (IOException e) {
eprintStackTrace();
}
}
private static ArrayList<File> getFile(File f) {
File[] ff = flistFiles();
for (File child : ff) {
if (childisDirectory()) {
getFile(child);
} else {
fileArrayadd(child);
}
}
return fileArray;
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)