代理服務程序是一種普遍使用的網絡應用程序。代理程序的種類很是多,根據協議不一樣能夠分紅HTTP代理服務程序、FTP代理服務程序等,而運行代理服務程序的服務器也就相應稱爲HTTP代理服務器和FTP代理服務器。本文將介紹用C#的Web代理服務程序代理的是HTTP協議。瀏覽器
1、網絡代理程序的優勢安全
代理服務所起的是一個橋的做用,它是網絡信息的中轉站。在網絡中應用代理服務通常是基於如下幾個緣由:服務器
(1)充分利用IP地址資源。在局域網中,通常對外的IP地址都是很是有限的,爲了保證局域網內部的主機都可以訪問互聯網資源,經過網絡代理就能夠實現。網絡
(2)可以保證網絡安全。網絡代理能夠充當內部網和互聯網之間的防火牆,經過過濾IP地址,限定某些IP地址對外部資源的訪問。多線程
(3)可以有效地隱藏本身的IP地址和主機名。因爲全部對外網的請求都是經過代理服務器實現的,因此目的主機只能知道代理服務器的IP地址。socket
(4)提升網絡速度。一般代理服務器都設有一個較大的硬盤緩衝區,它存儲界數據,當你再訪問相同的數據時,則能夠直接從緩衝區中取出信息,從而提升訪問速度。tcp
2、網絡代理的類型及實現原理編輯器
網絡代理服務根據工做層次,通常可分爲應用層代理、傳輸層代理和SOCKS代理。應用層代理是工做在TCP/IP參考模型的應用層之上,它支持對應用層協議(如HTTP、FTP)的代理。它提供的控制最多,可是不靈活,必需要有相應的協議支持。若是協議不支持代理(如SMTP和POP),那就只能在應用層如下代理,也即傳輸層代理。ide
傳輸層代理直接與TCP層交互,更加靈活。要求代理服務器具備部分真正服務器的功能:監聽特定TCP或UDP端口,接收客戶端的請求同時向客戶端發出相應的響應。另外一種代理須要改變客戶端的IP棧,即SOCKS代理。它是可用的最強大、最靈活的代理標準協議。SOCK V4容許代理服務器內部的客戶端徹底地鏈接到外部的服務器,SOCK V5增長了對客戶端的受權和認證,所以它是一種安全性較高的代理。本節後面介紹的代理是一種應用層上面的代理,所代理的協議是HTTP,也就是常常見到的Web代理服務器。函數
正如上面所說,網絡代理就是一個鏈接客戶端(須要代理的計算機)和服務器端(提供訪問資源的服務器)的橋。要實現這種橋的功能,網絡代理就必須知足下列條件,其實也是代理服務的運行的流程:
(1)接收並解析客戶端的請求。
(2)建立到服務器的新鏈接,並轉發客戶端的請求信息。
(3)接收服務器反饋的信息。
(4)解釋服務器的響應並將該響應傳回給客戶端。
網絡代理雖然有不少優勢,但因爲使用代理後,本身對網絡的全部請求都是經過代理服務器這個中間人來實現的,因此有可能碰上存有惡意的人監聽你的輸入的內容。一樣,若是選擇的代理服務器的帶寬比較小,使用代理還會下降網速。
總而言之,使用代理有利有弊,使用者要根據自身的狀況來決定。但不管如何,選擇一個好的代理服務器是很是重要的。
3、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」。
下面就開始C#實現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;
- strRetPagestrRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, rBytes);
- while (rBytes > 0)
- {
- rBytes = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
- strRetPagestrRetPage = 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),(這些設置不會應用於撥號和×××鏈接)」多選框,並在其中的「地址」文本框中輸入代理服務器的IP地址,好比「10.138.198.213」,在「端口」文本框中輸入「8000」。
此時客戶端的設置就完成了。在肯定IP地址爲「10.138.198.213」的這臺計算機已經運行上面介紹的Web代理程序後,打開客戶端的IE瀏覽器,並輸入要瀏覽的網址,就能夠經過Web代理服務器來瀏覽網頁了。
4、C#實現Web代理服務器總結
至此一個簡單的C#實現Web代理服務器軟件就算基本完成了。雖然Web代理服務器的實現原理相對簡單,但具體實現仍是很繁瑣的。網絡代理是一個內容豐富,實現複雜的論題,本節介紹的代理服務軟件,不管在實現的協議種類,仍是實現的功能,都只能算很小的一部分。但願各位可以經過本文的介紹,結合其餘相關的知識,創造出功能更強大、安全性更高,使用更穩定的網絡代理服務程序來。