国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

Visual C#實現HTTP代理服務程序

2024-07-21 02:29:37
字體:
來源:轉載
供稿:網友
  網絡代理程序的種類非常多,根據代理服務程序代理的協議不同,分成http代理服務程序、ftp代理服務程序等,運行代理服務程序的服務器也就稱為http代理服務器和ftp代理服務器。在本節中介紹的web代理服務程序代理的就是http協議。

  一.網絡代理的類型及實現原理:

  網絡代理服務根據工作層次,一般可分為應用層代理、傳輸層代理和socks代理。應用層代理是工作在tcp/ip參考模型的應用層之上,它支持對應用層協議(如http,ftp)的代理。它提供的控制最多,但是不靈活,必須要有相應的協議支持。如果協議不支持代理(如smtp和pop),那就只能在應用層以下代理,也即傳輸層代理。傳輸層代理直接與tcp層交互,更加靈活。要求代理服務器具有部分真正服務器的功能:監聽特定tcp或udp端口,接收客戶端的請求同時向客戶端發出相應的響應。另一種代理需要改變客戶端的ip棧,即socks代理。它是可用的最強大、最靈活的代理標準協議。sock v4允許代理服務器內部的客戶端完全地連接到外部的服務器,sock v5增加了對客戶端的授權和認證,因此它是一種安全性較高的代理。本節后面介紹的代理是一種應用層上面的代理,所代理的協議是http,也就是經常見到的web代理。

  網絡代理就是一個連接客戶端(設定需要代理的計算機)和服務器端(需要訪問資源的服務器)的橋。要實現這種橋,網絡代理就必須滿足下列條件,其實也是代理服務的運行的流程:

 ?。?). 能夠接收并解析客戶端的請求。

 ?。?). 創建到服務器的新連接,并根據轉發客戶端的請求信息。

 ?。?). 接收服務器反饋的信息。

 ?。?). 能夠發出或解釋服務器的響應并將該響應傳回給客戶端。

  圖01是網絡代理服務的一個典型模型圖:


圖01:代理服務的模型

  二.visual c#實現web代理服務程序

  web代理服務是代理服務中最常用的一種代理服務,按照代理服務的層次,它屬于應用層代理,是對tcp/ip參考模型中的應用層的http協議的代理。

  web代理服務也是代理服務中的一種,所以它也要滿足代理服務的基本條件。在下面介紹的代理服務程序中,是按照下列的順序來實現其功能的。

 ?。?). 代理服務器程序偵聽端口,接收客戶端瀏覽器發送來的web請求信息。

 ?。?). 代理服務器程序接收到客戶端web請求信息后,解析出web服務器的地址,并創建一個socket實例,并以此實例連接web服務器上。

 ?。?). 通過創建的socket傳送客戶端的web請求數據包到web服務器的80端口。

 ?。?). 代理服務器程序接收web服務器返回頁面數據。

  (5). 代理服務器程序把接收來的數據傳送到客戶端,實現web代理。

  由于客戶端的對一個地址的瀏覽,要傳送很多的web請求信息,為了更快、更準確的處理這些信息,web代理服務程序采用了多線程來處理每一個web請求。細心的讀者可能會發現,處理每一個客戶端的web請求信息,代理服務器軟件都要使用二個socket,一個是用來接收/傳送客戶機的信息,一個是和web服務器進行交流。為了區分這二個socket,我們把他們都命名,和服務器對話的socket,稱為服務socket;和客戶端機器對話的scoket,稱為客戶socket。

  下面就開始web代理服務程序的編寫工作。

  這個示例主要包含三個部分內容:

  ·創建一個web代理類。

  ·web代理服務的類的實例化。

  ·如何通過這個web代理類的實例實現web代理服務。

  下面就是第一部分的具體的實現步驟。

  (一).創建一個web代理類

  以下是具體的操作步驟如下:

  1. 首先啟動visual studio .net,依次選擇"文件"、"新建"、"項目"菜單后,在彈出"新建項目"對話框中將"項目類型"設置為"visual c#項目",將"模板"設置為"windows應用程序",在"名稱"文本框中輸入"webproxy",在"位置"的文本框中輸入"e:/vs.net項目",然后單擊"確定"按鈕。這樣在"e:/vs.net項目"目錄中就創建了一個新名稱為"webproxy"文件夾,里面存放的就是"webproxy"的項目文件。

  2. 選擇菜單【項目】|【添加類】,彈出【添加新項】對話框

  3. 將【模板】設置【類】

  4. 在【名稱】文本框中輸入【proxy】,單擊【打開】按鈕,具體如圖02所示。


圖02:web代理項目中【添加新項】對話框

  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類中的run方法,run方法是proxy類中唯一的方法。其功能是從客戶端接收http請求,并傳送到web服務器,然后從web服務器接收反饋來的數據,并傳送到客戶端。為了實現這二個不同方面的數據傳送,run方法中是通過二個socket實例來實現的。在編寫run方法的時候,要注意下面幾點:

 ?。?). 由于http是tcp/ip參考模型中的應用層協議,它建立于tcp協議之上,所以創建的socket實例使用的協議類型應該為tcp協議。下面代碼是創建可以傳送http請求命令到web服務器和接收來自web服務器反饋來信息的socket實例:

socket ipsocket = new socket(addressfamily.internetwork, sockettype.stream,protocoltype.tcp);

 ?。?). 另外一個socket是在代理服務程序偵聽端口號,接收掛起的連接請求時候得到的,以此socket為參數,利用proxy類中的構造函數,來創建一個proxy實例的。此socket實現從客戶端接收http請求信息,并傳送數據到客戶端。

  socket創建和使用是實現web代理軟件的關鍵,具體實現方法是在構造函數代碼后面,輸入下列代碼,創建proxy類的run方法:

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 )
 {
  console.writeline ( exc2.tostring ( ) ) ;
 }
}
//接收客戶端的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 ) ;
}

  9. 在定義proxy類代碼區中加入下列代碼,下列代碼是定義proxy類中的使用的一些變量,這些變量主要是在后面的定義run方法中使用。

socket clientsocket ;
byte[] read = new byte[1024] ;
//定義一個空間,存儲來自客戶端請求數據包
byte [] buffer = null ;
encoding ascii = encoding.ascii ;
//設定編碼
byte[] recvbytes = new byte[4096] ;
//定義一個空間,存儲web服務器返回的數據

  10. 至此,proxy類的定義過程就完成了。把proxy類實例化非常簡單,和以前用的其他完全一樣,具體語法如下:

public proxy ( socket socket );

  參數:socket為一個scoket實例

  下面代碼是創建一個proxy實例:

proxy proxy = new proxy ( socket ) ;
 ?。ǘ? 利用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 ;
//其中命名空間webproxy是proxy類所處的位置,具體可以參閱proxy.cs源文件
//中命名空間的定義。

  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地址,由于測試的代理服務器的ip地址為"10.138.198.213",所有也輸入此ip地址,在【端口】文本框中輸入"8000"。具體如圖03所示:


圖03:客戶端設定web代理服務器對話框

  此時客戶端的設置就完成了,在確定ip地址為"10.138.198.213"的這臺計算機已經運行上面介紹的web代理程序后。打開客戶端的ie瀏覽器,并輸入要瀏覽的網址,就可以通過web代理服務器來瀏覽網頁了,圖04是web代理服務程序在服務器端運行時的界面。


圖04:web代理服務程序在服務器端的運行界面

  四.總結

  至此一個簡單的web代理服務軟件就算基本完成了,通過上面內容的介紹可見,雖然代理服務的實現原理相對簡單,但具體實現其實還是很繁瑣的。網絡代理是一個內容豐富,實現復雜的論題,本節介紹的代理服務軟件,無論在實現的協議種類,還是實現的功能,都只能算很小的一部分。希望各位能夠通過本文的介紹,結合其他相關的知識,創造出功能更強大、安全性更高,使用更穩定的網絡代理服務程序來。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金秀| 峨边| 富平县| 新巴尔虎右旗| 资兴市| 金昌市| 衡南县| 林口县| 上虞市| 南部县| 任丘市| 大邑县| 临西县| 新晃| 九台市| 南陵县| 连云港市| 介休市| 尼玛县| 洞头县| 德钦县| 四会市| 九台市| 什邡市| 文安县| 龙门县| 陆河县| 长寿区| 五寨县| 井冈山市| 罗江县| 鹤峰县| 金堂县| 潜江市| 长白| 尼玛县| 斗六市| 诏安县| 弥渡县| 呼伦贝尔市| 肃宁县|