代理伺服器的作用,就是作為連線來源端與連線目的端之間的橋樑,代理伺服器的功能有很多種,有作為網頁快取的代理伺服器,有作為防火牆功能的代理伺服器,有作為訊息過濾的代理伺服器等等。
客戶端 <----> 代理伺服器 <----> 目的伺服器
其實將代理伺服器的功能簡化至最基本時,其功能就是將連線來源端的訊息轉接至連線目的端,而連線目的端的訊息轉接至連線來源端,對連線來源端而言,代理伺服器像是伺服端,對連線目的端而言,代理伺服器像是客戶端。
訊息在代理伺服器時所作的處理,決定了代理伺服器的種類,如果它將網頁暫存在伺服器本身的儲存裝置,並供客戶端直接比對下載,它的作用就是網頁代理伺服
器,如果它的作用在過濾進出代理伺服器的訊息,它的作用就有些像是防火牆的功能(當然必須實作低階的封包過濾才算真正是),您也可以設計一個代理伺服器,
專門過濾掉網頁上的廣告部份。
下面這個程式即實作一個最簡單的代理伺服器功能,它將連線來源端的訊息轉接至連線目的端,而連線目的端的訊息轉接至連線來源端,為了簡化程式邏輯,這個程式一次只能服務一個連線:
package onlyfun.caterpillar;
import java.io.*; import java.net.*;
public class SimpleProxyServer { public static void main(String[] args) { String host; // 代理的對象主機 int remotePort; // 代理對象連接埠 int localPort; // 本機連接埠 BufferedReader reader;
try { reader = new BufferedReader( new InputStreamReader(System.in));
System.out.println("SimpleProxyServer v0.1"); System.out.print("代理的對象主機: "); host = reader.readLine(); System.out.print("代理對象連接埠: "); remotePort = Integer.parseInt(reader.readLine()); System.out.print("本機連接埠: "); localPort = Integer.parseInt(reader.readLine());
runServer(host, remotePort, localPort); } catch(IOException e) { System.err.println(e.toString()); } }
public static void runServer(String host, int remotePort, int localPort) { try { System.out.printf("Proxy伺服器啟動...Port %d%n", localPort); ServerSocket proxyServerSkt = new ServerSocket(localPort); System.out.println("OK!");
while(true) { System.out.println("傾聽客戶端....."); Socket clientSkt = proxyServerSkt.accept(); System.out.printf("%s 連線..%n", clientSkt.getInetAddress().toString());
// 客戶端的來往訊息 final BufferedInputStream clientInputStream = new BufferedInputStream(clientSkt.getInputStream()); PrintStream clientPrintStream = new PrintStream(clientSkt.getOutputStream());
// 伺服端的來往訊息 final Socket serverSkt = new Socket(host, remotePort); BufferedInputStream fromServerMsg = new BufferedInputStream( serverSkt.getInputStream()); final PrintStream serverPrintStream = new PrintStream(serverSkt.getOutputStream());
// 由客戶端至伺服器的訊息溝通執行緒 Thread client = new Thread() { public void run() { int read; try { while((read = clientInputStream.read()) != -1) { serverPrintStream.write(read); serverPrintStream.flush(); } } catch(IOException e) {}
// 中斷至伺服器的連線 try { serverSkt.close(); } catch(IOException e) { System.err.println(e.toString()); } } };
client.start();
// 主執行緒為由伺服器至客戶端的訊息 int read; try { while((read = fromServerMsg.read()) != -1) { clientPrintStream.write(read); clientPrintStream.flush(); } } catch(IOException e) { e.printStackTrace(); };
// 中斷與客戶端的連線 try { clientSkt.close(); } catch(IOException e) { e.printStackTrace(); } } } catch(UnknownHostException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } }
您有幾個方法可以測試這個程式,首先啟動程式:
SimpleProxyServer v0.1
代理的對象主機: ptt.cc
代理對象連接埠: 23
本機連接埠: 23
Proxy伺服器啟動...Port 23..OK!
傾聽客戶端.....
|
範例在本機8888連接埠啟動了代理伺服器,代理的對象是ptt.cc,接下來您可以直接telnet localhost 23,本機所啟動的代理伺服器會幫您連線至ptt.cc,接下來的一切操作就與BBS操作相同了。
您也可以讓它代理一個Web伺服器,假設本機代理伺服器連接埠也設定為8080,當使用瀏覽器鍵入http://localhost:8080/時,您會發現瀏覽器自動連接至代理的網頁伺服器。
|
|