構造.NET環境下的網頁下載器(1)

發表于:2007-05-25來源:作者:點擊數: 標簽:網頁.NET下載構造環境
一.前言: 微軟的.Net框架為我們進行網絡編程提供了以下兩個名字空間:System.Net以及System.Net.Sockets。通過合理運用其中的類和方法,我們可以很容易地編寫出各種網絡應用程序。這種網絡應用程序既可以是基于流套接字的,也可以是基于數據報套接字的。而
一.前言:

  微軟的.Net框架為我們進行網絡編程提供了以下兩個名字空間:System.Net以及System.Net.Sockets。通過合理運用其中的類和方法,我們可以很容易地編寫出各種網絡應用程序。這種網絡應用程序既可以是基于流套接字的,也可以是基于數據報套接字的。而基于流套接字的通訊中采用最廣泛的協議就是TCP協議,基于數據報套接字的通訊中采用最廣泛的自然就是UDP協議了。下面我將重點向大家介紹.NET網絡編程中的一些類:Dns類、IPHostEntry類、IPEndPoint類以及Socket類,并會在最后給出一個網頁下載器的實例以加深讀者對.NET網絡編程的理解。

  二.網絡編程類介紹:

  Dns 類:

  向使用 TCP/IP Internet 服務的應用程序提供域名服務。其Resolve()方法查詢DNS服務器以將用戶友好的域名(如"www.google.com")映射到數字形式的 Internet 地址(如 192.168.1.1)。Resolve()方法返回一個IPHostEnty實例,該實例包含所請求名稱的地址和別名的列表。大多數情況下,可以使用 AddressList 數組中返回的第一個地址。

  Resolve()方法的函數原型如下:

  public static IPHostEntry Resolve(string hostName);



  下面的代碼獲取一個 IPAddress 實例,該實例包含服務器 www.google.com 的IP地址:

  IPHostEntry ipHostInfo = Dns.Resolve("www.google.com");
  IPAddress ipAddress = ipHostInfo.AddressList[0];



  不過在Dns類中,除了通過Resolve()方法,你還可以通過GetHostByAddress()方法以及GetHostByName()方法來得到相應的IPHostEntry實例,函數原型如下:

  public static IPHostEntry GetHostByAddress(string IPAddress);
  public static IPHostEntry GetHostByName(string hostName);



  下面的代碼顯示了如何分別運用以上兩種方法獲得包含服務器www.google.com的相關信息的IPHostEntry實例:

  IPHostEntry hostInfo=Dns.GetHostByAddress("192.168.1.1");
  IPHostEntry hostInfo=Dns.GetHostByName("www.google.com");



  在使用以上方法時,你將可能需要處理以下幾種異常:

  SocketException異常:訪問Socket時操作系統發生錯誤引發

  ArgumentNullException異常:參數為空引用引發

  ObjectDisposedException異常:Socket已經關閉引發

  以上,我向大家簡要地介紹了Dns類中一些方法以及其用法,并列舉出了可能出現的異常,下面就讓我們轉到和Dns類密切相關的IPHostEntry類。
 IPHostEntry類:

  該類的實例對象中包含了Internet主機的地址相關信息。此類型的所有公共靜態成員對多線程操作而言都是安全的,但不保證任何實例成員是線程安全的。其中主要的一些屬性有:AddressList屬性、Aliases屬性以及HostName屬性。

  AddressList屬性和Aliases屬性的作用分別是獲取或設置與主機關聯的IP地址列表以及獲取或設置與主機關聯的別名列表。其中AddressList屬性值是一個IPAddress類型的數組,包含解析為Aliases屬性中包含的主機名的IP地址;Aliases屬性值是一組字符串,包含解析為AddressList 屬性中的IP地址的DNS名。而HostName屬性比較好理解,它包含了服務器的主要主機名,這光從名稱上就可以知道了。如果服務器的DNS項定義了附加別名,則可在Aliases屬性中使用這些別名。

  下面的代碼列出了服務器www.google.com的相關別名列表以及IP地址列表的長度并將所有的IP地址列出:

  IPHostEntry IPHost = Dns.Resolve("www.google.com/");
  string[] aliases = IPHost.Aliases;
  Console.WriteLine(aliases.Length);

  IPAddress[] addr = IPHost.AddressList;
  Console.WriteLine(addr.Length);
  for(int i= 0; i < addr.Length ; i++)
  {
  Console.WriteLine(addr[i]);
  }


  介紹完IPHostEntry類,我們能獲得了所要連接的主機的相關IP地址以及別名列表,但是真正要和主機取得連接還需要一個很重要的類-IPEndPoint類。


  IPEndPoint類:

  在Internet中,TCP/IP使用一個網絡地址和一個服務端口號來唯一標識設備。網絡地址標識網絡上的特定設備;端口號標識要連接到的該設備上的特定服務。網絡地址和服務端口的組合稱為終結點,在.NET框架中正是由EndPoint類表示這個終結點,它提供表示網絡資源或服務的抽象,用以標志網絡地址等信息。.Net同時也為每個受支持的地址族定義了 EndPoint的子代;對于IP地址族,該類為IPEndPoint。IPEndPoint類包含應用程序連接到主機上的服務所需的主機和端口信息,通過組合服務的主機IP地址和端口號,IPEndPoint類形成到服務的連接點。

  在IPEndPoint類中有兩個很有用的構造函數:

  public IPEndPoint(long, int);
  public IPEndPoint(IPAddress, int);



  它們的作用就是用指定的地址和端口號初始化 IPEndPoint 類的新實例。該類中的屬性有:Address屬性、AddressFamily屬性以及Port屬性,這些屬性相對比較容易理解,這里就不作多介紹。下面的代碼顯示了如何取得服務器www.google.com的終結點:

  IPHostEntry IPHost = Dns.Resolve("www.google.com");
  IPAddress[] addr = IPHost.AddressList;
  IPEndPoint ep = new IPEndPoint(addr[0],80);


  這樣,我們已經了解了和主機取得連接的一些必要的基本類,有了這些知識,我們就可以運用下面的Socket類真正地和主機取得連接并進行通訊了。

  Socket類:

  Socket類是包含在System.Net.Sockets名字空間中的一個非常重要的類。一個Socket實例包含了一個本地以及一個遠程的終結點,就像上面介紹的那樣,該終結點包含了該Socket實例的一些相關信息。

  需要知道的是Socket 類支持兩種基本模式:同步和異步。其區別在于:在同步模式中,對執行網絡操作的函數(如Send和Receive)的調用一直等到操作完成后才將控制返回給調用程序。在異步模式中,這些調用立即返回。

  下面我們重點討論同步模式的Socket編程。首先,同步模式的Socket編程的基本過程如下:

  1.創建一個Socket實例對象。

  2.將上述實例對象連接到一個具體的終結點(EndPoint)。

  3.連接完畢,就可以和服務器進行通訊:接收并發送信息。

  4.通訊完畢,用ShutDown()方法來禁用Socket。

  5.最后用Close()方法來關閉Socket。

  知道了以上基本過程,我們就開始進一步實現連接并通訊了。在使用之前,你需要首先創建Socket對象的實例,這可以通過Socket類的構造方法來實現:

  public Socket(AddressFamily addressFamily,SocketType
  socketType,ProtocolType protocolType);


  其中,addressFamily 參數指定Socket使用的尋址方案,比如AddressFamily.InterNetwork表明為IP版本4的地址;socketType參數指定Socket的類型,比如SocketType.Stream表明連接是基于流套接字的,而SocketType.Dgram表示連接是基于數據報套接字的。protocolType參數指定Socket使用的協議,比如ProtocolType.Tcp表明連接協議是運用TCP協議的,而Protocol.Udp則表明連接協議是運用UDP協議的。

  在創建了Socket實例后,我們就可以通過一個遠程主機的終結點和它取得連接,運用的方法就是Connect()方法:

  public Connect (EndPoint ep);


  該方法只可以被運用在客戶端。進行連接后,我們可以運用套接字的Connected屬性來驗證連接是否成功。如果返回的值為true,則表示連接成功,否則就是失敗。下面的代碼就顯示了如何創建Socket實例并通過終結點與之取得連接的過程:

IPHostEntry IPHost = Dns.Resolve("http://www.google.com/");
string []aliases = IPHost.Aliases;
IPAddress[] addr = IPHost.AddressList;
EndPoint ep = new IPEndPoint(addr[0],80);

Socket sock = newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
sock.Connect(ep);
if(sock.Connected)
Console.WriteLine("OK");


  一旦連接成功,我們就可以運用Send()和Receive()方法來進行通訊。

  Send()方法的函數原型如下:

  public int Send (byte[] buffer, int size, SocketFlags flags);


  其中,參數buffer包含了要發送的數據,參數size表示要發送數據的大小,而參數flags則可以是以下一些值:SocketFlags.None、SocketFlags.DontRoute、SocketFlags.OutOfBnd。

  該方法返回的是一個System.Int32類型的值,它表明了已發送數據的大小。同時,該方法還有以下幾種已被重載了的函數實現:

public int Send (byte[] buffer);
public int Send (byte[] buffer, SocketFlags flags);
public int Send (byte[] buffer,int offset, int size,
SocketFlags flags);


  介紹完Send()方法,下面是Receive()方法,其函數原型如下:

  public int Receive(byte[] buffer, int size, SocketFlags flags);


  其中的參數和Send()方法的參數類似,在這里就不再贅述。

  同樣,該方法還有以下一些已被重載了的函數實現:

public int Receive (byte[] buffer);
public int Receive (byte[] buffer, SocketFlags flags);
public int Receive (byte[] buffer,int offset, int size,
SocketFlags flags);


  在通訊完成后,我們就通過ShutDown()方法來禁用Socket,函數原型如下:

  public void ShutDown(SocketShutdown how);


  其中的參數how表明了禁用的類型,SoketShutdown.Send表明關閉用于發送的套接字;SoketShutdown.Receive表明關閉用于接收的套接字;而SoketShutdown.Both則表明發送和接收的套接字同時被關閉。

  應該注意的是在調用Close()方法以前必須調用ShutDown()方法以確保在Socket關閉之前已發送或接收所有掛起的數據。一旦ShutDown()調用完畢,就調用Close()方法來關閉Socket,其函數原型如下:

  public void Close();

  該方法強制關閉一個Socket連接并釋放所有托管資源和非托管資源。該方法在內部其實是調用了方法Dispose(),該函數是受保護類型的,其函數原型如下:

  protected virtual void Dispose(bool disposing);

  其中,參數disposing為true或是false,如果為true,則同時釋放托管資源和非托管資源;如果為false,則僅釋放非托管資源。因為Close()方法調用Dispose()方法時的參數是true,所以它釋放了所有托管資源和非托管資源。

  這樣,一個Socket從創建到連接到通訊最后的關閉的過程就完成了。雖然整個過程比較復雜,但相對以前在SDK或是其他環境下進行Socket編程,這個過程就顯得相當輕松了。

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97