代理服務程式是一種廣泛使用的網絡應用程式。代理程式的種類非常多,根據協定不同可以分成HTTP代理服務程式、FTP代理服務程式等,而運作代理服務程式的伺服器也就相應稱為HTTP代理伺服器和FTP代理伺服器。本文将介紹的Web代理服務程式代理的是HTTP協定。
一、網絡代理程式的優點
代理服務所起的是一個橋的作用,它是網絡資訊的中轉站。在網絡中應用代理服務一般是基于以下幾個原因:
(1)充分利用IP位址資源。在區域網路中,一般對外的IP位址都是非常有限的,為了保證區域網路内部的主機都能夠通路網際網路資源,通過網絡代理就可以實作。
(2)能夠保證網絡安全。網絡代理可以充當内部網和網際網路之間的防火牆,通過過濾IP位址,限定某些IP位址對外部資源的通路。
(3)能夠有效地隐藏自己的IP位址和主機名。由于所有對外網的請求都是通過代理伺服器實作的,是以目的主機隻能知道代理伺服器的IP位址。
(4)提高網絡速度。通常代理伺服器都設有一個較大的硬碟緩沖區,它存儲界資料,當你再通路相同的資料時,則可以直接從緩沖區中取出資訊,進而提高通路速度。
二、網絡代理的類型及實作原理
網絡代理服務根據工作層次,一般可分為應用層代理、傳輸層代理和SOCKS代理。應用層代理是工作在TCP/IP參考模型的應用層之上,它支援對應用層協定(如HTTP、FTP)的代理。它提供的控制最多,但是不靈活,必須要有相應的協定支援。如果協定不支援代理(如SMTP和POP),那就隻能在應用層以下代理,也即傳輸層代理。傳輸層代理直接與TCP層互動,更加靈活。要求代理伺服器具有部分真正伺服器的功能:監聽特定TCP或UDP端口,接收用戶端的請求同時向用戶端發出相應的響應。另一種代理需要改變用戶端的IP棧,即SOCKS代理。它是可用的最強大、最靈活的代理标準協定。SOCK V4允許代理伺服器内部的用戶端完全地連接配接到外部的伺服器,SOCK V5增加了對用戶端的授權和認證,是以它是一種安全性較高的代理。本節後面介紹的代理是一種應用層上面的代理,所代理的協定是HTTP,也就是經常見到的Web代理。
正如上面所說,網絡代理就是一個連接配接用戶端(需要代理的計算機)和伺服器端(提供通路資源的伺服器)的橋。要實作這種橋的功能,網絡代理就必須滿足下列條件,其實也是代理服務的運作的流程:
(1)接收并解析用戶端的請求。
(2)建立到伺服器的新連接配接,并轉發用戶端的請求資訊。
(3)接收伺服器回報的資訊。
(4)解釋伺服器的響應并将該響應傳回給用戶端。
網絡代理雖然有很多優點,但由于使用代理後,自己對網絡的所有請求都是通過代理伺服器這個中間人來實作的,是以有可能碰上存有惡意的人監聽你的輸入的内容。同樣,如果選擇的代理伺服器的帶寬比較小,使用代理還會降低網速。
總而言之,使用代理有利有弊,使用者要根據自身的情況來決定。但無論如何,選擇一個好的代理伺服器是非常重要的。
三、C#實作Web代理服務程式
經過了上面的介紹,我想大家對代理服務應該有了一個基本的認識,下面就讓我們通過一個執行個體來深入體會一下如何用C#實作Web代理服務。Web代理服務的功能順序是這樣的:
(1)偵聽端口,等待用戶端浏覽器發送來的Web請求資訊。
(2)接收到用戶端Web請求資訊後,解析出目标Web伺服器的位址,并建立一個Socket執行個體,并以此執行個體連接配接Web伺服器上。
(3)通過建立的Socket傳送用戶端的Web請求資料包到Web伺服器的80端口。
(4)接收Web伺服器傳回的頁面資料。
(5)把接收來的資料傳送到用戶端,進而實作Web代理。
用戶端對某個Web位址的浏覽,可能要傳送很多的Web請求資訊(比如網頁中的圖像、Flash等),為了更快更準确地處理這些資訊,Web代理服務程式通常采用多線程來處理每一個Web請求。細心的讀者可能會發現,處理每一個用戶端的Web請求資訊,代理伺服器軟體都要使用二個Socket,一個是用來接收/傳送客戶機的資訊,一個是和Web伺服器進行交流。為了區分這二個Socket,我們把和伺服器對話的稱為“服務Socket”,和用戶端機器對話的稱為“客戶Socket”。
下面就開始Web代理服務程式的編寫工作。這個執行個體包含三個部分内容:
1.建立一個Web代理類。
2.Web代理服務的類的執行個體化。
3.如何通過這個Web代理類的執行個體實作Web代理服務。
(一)建立一個Web代理類
具體操作步驟如下:
1.啟動Visual Studio.Net,依次選擇“檔案”、“建立”、“項目”菜單後,在彈出“建立項目”對話框中将“項目類型”設定為“Visual C#項目”,将“模闆”設定為“Windows應用程式”,在“名稱”文本框中輸入“WebProxy”,在“位置”文本框中輸入“E:VS.NET項目”,然後單擊“确定”按鈕,這樣項目便建立好了。
2.依次選擇菜單“項目”、“添加類”,将彈出“添加新項”對話框。
3.将“模闆”設定為“類”。
4.在“名稱”文本框中輸入“Proxy”,單擊“打開”按鈕
5.在“解決方案資料總管”視窗中,輕按兩下Proxy.cs檔案,進入Proxy.cs檔案的編輯界
6.在Proxy.cs源檔案的開頭,添加下列代碼,下列代碼是導入Proxy.cs中要使用到的命名空間:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
7.用下列構造函數替代預設的構造函數。下面的代碼是在Proxy類中建立一個構造函數。Proxy類隻有一個構造函數,并且這個構造函數隻有一個參數,這個參數是Socket對象,它主要用來和用戶端進行資料交換,是一個“客戶Socket”:
public Proxy(Socket socket)
{
//
// TODO: 在此處添加構造函數邏輯
//
this.clientSocket = socket ;
}
8.在定義Proxy類代碼區中加入下列代碼,下列代碼是定義Proxy類中的使用的一些變量,這些變量主要是在後面的定義Run方法中使用。
Socket clientSocket;
Byte[] read = new byte[1024];
//定義一個空間,存儲來自用戶端請求資料包
Byte [] Buffer = null;
Encoding ASCII = Encoding.ASCII;
//設定編碼
Byte[] RecvBytes = new Byte[4096];
//定義一個空間,存儲Web伺服器傳回的資料
9.建立Proxy類中的Run方法。Run方法是Proxy類中唯一的方法。其功能是從用戶端接收HTTP請求,并傳送到Web伺服器,然後從Web伺服器接收回報來的資料,并傳送到用戶端。為了實作這二個不同方面的資料傳送,Run方法中是通過兩個Socket執行個體來實作的。在編寫Run方法的時候,要注意下面兩點:
(1)由于HTTP建立于TCP協定之上,是以建立的Socket執行個體應該使用TCP協定。下面代碼是建立可以傳送HTTP請求指令到Web伺服器和接收來自Web伺服器回報來資訊的Socket執行個體:
Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
(2)另外一個Socket是在代理服務程式偵聽端口号,接收連接配接請求時候得到的,是以應該以此Socket為參數,利用Proxy類中的構造函數來建立一個Proxy執行個體。此Socket實作從用戶端接收HTTP請求資訊,并傳送資料到用戶端。
Socket建立和使用是實作Web代理軟體的關鍵。在構造函數代碼後面,輸入下列代碼:
public void Run()
{
string clientmessage = " " ;
//存放來自用戶端的HTTP請求字元串
string URL = " " ;
//存放解析出位址請求資訊
int bytes = ReadMessage(read, ref clientSocket, ref clientmessage);
if (bytes == 0)
{
return ;
}
int index1 = clientmessage.IndexOf(' ');
int index2 = clientmessage.IndexOf(' ', index1 + 1);
if ((index1 == -1) || (index2 == -1))
{
throw new IOException();
}
string part1 = clientmessage.Substring(index1 + 1, index2 - index1);
int index3 = part1.IndexOf('/', index1 + 8);
int index4 = part1.IndexOf(' ', index1 + 8);
int index5 = index4 - index3;
URL = part1.Substring(index1 + 4, (part1.Length - index5) - 8);
try
{
IPHostEntry IPHost = Dns.Resolve(URL);
Console.WriteLine("遠端主機名: " + IPHost.HostName);
string [] aliases = IPHost.Aliases;
IPAddress[] address = IPHost.AddressList;
Console.WriteLine("Web伺服器IP位址:" + address[0]);
//解析出要通路的伺服器位址
IPEndPoint ipEndpoint = new IPEndPoint(address[0], 80);
Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//建立連接配接Web伺服器端的Socket對象
IPsocket.Connect(ipEndpoint);
//Socket連Web接伺服器
if (IPsocket.Connected)
Console.WriteLine("Socket 正确連接配接!");
string GET = clientmessage;
Byte[] ByteGet = ASCII.GetBytes(GET);
IPsocket.Send(ByteGet, ByteGet.Length, 0);
//代理通路軟體對伺服器端傳送HTTP請求指令
Int32 rBytes = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
//代理通路軟體接收來自Web伺服器端的回報資訊
Console.WriteLine("接收位元組數:" + rBytes.ToString());
String strRetPage = null;
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, rBytes);
while (rBytes > 0)
{
rBytes = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, rBytes);
}
IPsocket.Shutdown(SocketShutdown.Both);
IPsocket.Close();
SendMessage(clientSocket, strRetPage);
//代理服務軟體往用戶端傳送接收到的資訊
}
catch (Exception exc2)
}
//接收用戶端的HTTP請求資料
private int ReadMessage(byte [] ByteArray, ref Socket s, ref String clientmessage)
{
int bytes = s.Receive(ByteArray, 1024, 0);
string messagefromclient = Encoding.ASCII.GetString(ByteArray);
clientmessage = (String)messagefromclient;
return bytes;
}
//傳送從Web伺服器回報的資料到用戶端
private void SendMessage(Socket s, string message)
{
Buffer = new Byte[message.Length + 1];
int length = ASCII.GetBytes(message, 0, message.Length, Buffer, 0);
Console.WriteLine("傳送位元組數:" + length.ToString());
s.Send(Buffer, length, 0);
}
至此,Proxy類的定義過程就完成了。
(二)利用Proxy類,實作Web代理
下面是利用Proxy類實作Web代理程式的具體實作步驟,Proxy類被定義在命名空間WebProxy中:
1.在Visual Studio .Net的代碼編輯器中打開Class1.cs檔案,進入Class1.cs的代碼編輯界面。
2.在Class1.cs源檔案的開頭導入下列命名空間:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Threading;
using WebProxy;
3.在Main函數中添加下列代碼,下列代碼是利用Proxy類,來實作Web代理程式:
const int port = 8000 ;
//定義端口号
TcpListener tcplistener = new TcpListener(port);
Console.WriteLine("偵聽端口号: " + port.ToString());
tcplistener.Start();
//偵聽端口号
while (true)
{
Socket socket = tcplistener.AcceptSocket();
//并擷取傳送和接收資料的Scoket執行個體
Proxy proxy = new Proxy(socket);
//Proxy類執行個體化
Thread thread = new Thread(new ThreadStart(proxy.Run));
//建立線程
thread.Start();
//啟動線程
}
儲存上面的所有步驟,這樣一個簡單Web代理程式就算是完成了。此Web代理程式偵聽的是8000端口号。
(三)測試Web代碼程式
Web代理程式要通過二台計算機才能夠實作,其中的一台計算機運作Web代理程式充當Web代理伺服器,另外一台計算機充當客戶機,通過Web代理伺服器來浏覽網頁。在确定Web代理軟體運作後,需要對客戶機進行進行必要的設定:
1.打開IE浏覽器。
2.依次選擇“工具”、“Internet選項”,在彈出的“Internet選項”對話框中選擇“連接配接”頁面,單擊其中的“區域網路設定”按鈕,在彈出的“區域網路(LAN)設定”對話框,選擇“為LAN使用代理伺服器(X),(這些設定不會應用于撥号和VPN連接配接)”多選框,并在其中的“位址”文本框中輸入代理伺服器的IP位址,比如“10.138.198.213”,在“端口”文本框中輸入“8000”。

此時用戶端的設定就完
在确定IP位址為“10.138.198.213”的這台計算機已經運作上面介紹的Web代理程式後,打開用戶端的IE浏覽器,并輸入要浏覽的網址,就可以通過Web代理伺服器來浏覽網頁了。圖4是Web代理服務程式在伺服器端運作時的界面:
四、總結
至此一個簡單的Web代理服務軟體就算基本完成了。雖然代理服務的實作原理相對簡單,但具體實作還是很繁瑣的。網絡代理是一個内容豐富,實作複雜的論題,本節介紹的代理服務軟體,無論在實作的協定種類,還是實作的功能,都隻能算很小的一部分。希望各位能夠通過本文的介紹,結合其他相關的知識,創造出功能更強大、安全性更高,使用更穩定的網絡代理服務程式來。