天天看點

C#網絡程式設計概述 二

轉自http://www.cnblogs.com/xh831213/archive/2006/02/13/329638.html

C#網絡程式設計概述 二
C#網絡程式設計概述 二

Code

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;

EndPoint ep = new IPEndPoint(addr[0],80);

Socket sock = new Socket(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程式設計,這個過程就顯得相當輕松了。

繼續閱讀