使用.NET訪問 Internet(3) Paul

來源:互聯網
上載者:User
訪問

使用 TCP 服務


TCPClient 類使用 TCP 從 Internet 資源請求資料。 TcpClient 的方法和屬性提取某個 Socket 執行個體的建立細節,該執行個體用於通過 TCP 請求和接收資料。由於到遠程裝置的串連表示為流,因此可以使用 .NET 架構流處理技術讀取和寫入資料。
TCP 協議建立與遠程終結點的串連,然後使用此串連發送和接收資料包。TCP 負責確保將資料包發送到終結點並在資料包到達時以正確的順序對其進行組合。
若要建立 TCP 串連,必須知道承載所需服務的網路裝置的地址以及該服務用於通訊的 TCP 通訊埠。Internet 分配號碼機構 (Internet Assigned Numbers Authority, IANA) 定義公用服務的連接埠號碼(請訪問 http://www.iana.org/assignments/port-numbers)。IANA 列表中所沒有的服務可使用 1,024 到 65,535 這一範圍中的連接埠號碼。
下列代碼說明如何設定 TcpClient 以串連到 TCP 通訊埠 13 上的時間伺服器。
[C#]
using System;
using System.Net.Sockets;
using System.Text;

public class TcpTimeClient {
  private const int portNum = 13;
  private const string hostName = "host.contoso.com";

  public static int Main(String[] args) {
    try {
      TcpClient client = new TcpClient(hostName, portNum);

      NetworkStream ns = client.GetStream();
      
      byte[] bytes = new byte[1024];
      int bytesRead = ns.Read(bytes, 0, bytes.Length);

      Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead));

      client.Close();

    } catch (Exception e) {
      Console.WriteLine(e.ToString());
    }

    return 0;
  }
}
TCPListener 用於監視 TCP 通訊埠上的傳入請求,然後建立 SocketTcpClient 執行個體來管理與用戶端的串連。Start 方法啟用偵聽,而 Stop 方法禁用連接埠上的偵聽。AcceptTcpClient 方法接受傳入的串連請求並建立 TcpClient 以處理請求,AcceptSocket 方法接受傳入的串連請求並建立 Socket 以處理請求。
下面的代碼說明如何使用 TcpListener 建立網路時間伺服器以監視 TCP 通訊埠 13。當接受傳入的串連請求時,時間伺服器用來自宿主伺服器的當前日期和時間進行響應。
[C#]
using System;
using System.Net.Sockets;
using System.Text;

public class TcpTimeServer {

  private const int portNum = 13;

  public static int Main(String[] args) {
    bool done = false;
    
    TcpListener listener = new TcpListener(portNum);

    listener.Start();

    while (!done) {
      Console.Write("Waiting for connection...");
      TcpClient client = listener.AcceptTcpClient();
      
      Console.WriteLine("Connection accepted.");
      NetworkStream ns = client.GetStream();

      byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());

      try {
        ns.Write(byteTime, 0, byteTime.Length);
        ns.Close();
        client.Close();
      } catch (Exception e) {
        Console.WriteLine(e.ToString());
      }
    }

    listener.Stop();

    return 0;
  }
  
}

使用 UDP 服務


UDPClient 類使用 UDP 與網路服務通訊。 UdpClient 類的屬性和方法提取某個 Socket 執行個體的建立細節,該樣本用於通過 UDP 請求和接收資料。
UDP 的優點是簡單易用,並且能夠同時向多個地址廣播訊息。但由於 UDP 協議是一個無連線協定,因此發送到遠程終結點的 UDP 資料文報不一定能夠到達,也不一定能夠以發送的相同順序到達。使用 UDP 的應用程式必須準備處理丟失的和順序有誤的資料文報。
若要使用 UDP 發送資料文報,必須知道承載所需服務的網路裝置的網路地址以及該服務用於通訊的 UDP 連接埠號碼。Internet 分配號碼機構 (Internet Assigned Numbers Authority, IANA) 定義公用服務的連接埠號碼(請訪問     http://www.iana.org/assignments/port-numbers)。IANA 列表中所沒有的服務可使用 1,024 到 65,535 這一範圍中的連接埠號碼。
特殊網路地址用於支援基於 IP 的網路上的 UDP 廣播訊息。下面探討的內容以 Internet 上使用的 IP 版本 4 地址族作為樣本。
IP 版本 4 地址使用 32 位指定網路地址。對於使用 255.255.255.0 網路遮罩的 C 類地址,這些位被分為四個八位位元組。當以十進位數表示時,這四個八位位元組構成熟悉的以點分隔的四部分標記法,如 192.168.100.2。前兩個八位位元組(此樣本中為 192.168)構成網路號;第三個八位位元組 (100) 定義子網;最後一個八位位元組 (2) 是主機標識符。
將 IP 位址的所有位均設定為 1(即 255.255.255.255)可構成有限的廣播位址。將 UDP 資料文報發送到此地址可將訊息傳遞到該廣播網路上的任何主機。由於路由器從不轉寄發送到此地址的訊息,因此只有已串連的網路上的主機才可看到這些廣播。
通過將部分地址的所有位全都設定為 1,可以將廣播定向到特定的網路部分。例如,若要將廣播發送到以 192.168 打頭的 IP 位址標識的網路上的所有主機,請將地址的子網和主機部分全都設定為 1,如 192.168.255.255。若要將廣播限制在單個子網,則只將主機部分設定全都為 1,如 192.168.100.255。
UdpClient 類可向任何網路廣播位址廣播,但它無法偵聽發送到網路的廣播。必須使用 Socket 類才能偵聽網路廣播。
當所有接收者都位於單個網路中時,或者當許多用戶端需要接收廣播時,廣播位址將起作用。當接收者為網路的一小部分時,應將訊息發送到多路廣播組,在那裡只有加入此組的用戶端才能接收到訊息。範圍從 224.0.0.2 到 244.255.255.255 的 IP 位址保留為主機群組地址。IP 號 224.0.0.0 被保留,而 224.0.0.1 分配給所有 IP 主機的固定組。
下面的樣本使用 UdpClient 偵聽連接埠 11000 上的多路廣播位址組 224.168.100.2 的 UDP 資料文報廣播。它接收訊息字串並將訊息寫入控制台。
 [C#]
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
 
public class UDPMulticastListener {
 
   private static readonly IPAddress GroupAddress = 
     IPAddress.Parse("224.168.100.2");
   private const int GroupPort = 11000;
   
  private static void StartListener() {
    bool done = false;
    
    UdpClient listener = new UdpClient();
    IPEndPoint groupEP = new IPEndPoint(GroupAddress,GroupPort);
 
    try {
      listener.JoinMulticastGroup(GroupAddress);
      listener.Connect(groupEP);
      
      while (!done) {
        Console.WriteLine("Waiting for broadcast");
        byte[] bytes = listener.Receive( ref groupEP);
 
        Console.WriteLine("Received broadcast from {0} :\n {1}\n",
          groupEP.ToString(),
          Encoding.ASCII.GetString(bytes,0,bytes.Length));
      }
 
      listener.Close();
      
    } catch (Exception e) {
      Console.WriteLine(e.ToString());
    }
    
  }
 
  public static int Main(String[] args) {
    StartListener();
 
    return 0;
  }
}

下面的樣本使用 UdpClient 將 UDP 資料文報發送到連接埠 11000 上的多路廣播位址組 224.268.100.2。它發送命令列上指定的訊息字串。
 [C#]
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
 
public class UDPMulticastSender {
 
   private static IPAddress GroupAddress = 
     IPAddress.Parse("224.168.100.2");
   private static int GroupPort = 11000;
   
  private static void Send( String message) {
    UdpClient sender = new UdpClient();
    IPEndPoint groupEP = new IPEndPoint(GroupAddress,GroupPort);
 
    try {
      Console.WriteLine("Sending datagram : {0}", message);
      byte[] bytes = Encoding.ASCII.GetBytes(message);
 
      sender.Send(bytes, bytes.Length, groupEP);
      
      sender.Close();
      
    } catch (Exception e) {
      Console.WriteLine(e.ToString());
    }
    
  }
 
  public static int Main(String[] args) {
    Send(args[0]);
 
    return 0;
  }
}
通訊端
System.Net.Sockets 命名空間包含 Windows 通訊端介面的託管實現。System.Net 命名空間中的所有其他網路訪問類都建立在該通訊端實現之上。
.NET 架構 Socket 類是 Winsock32 API 提供的通訊端服務的Managed 程式碼版本。大多數情況下, Socket 類方法只是將資料封送到它們的本機 Win32 副本中並處理任何必要的安全檢查。
Socket 類支援兩種基本模式:同步和非同步。在同步模式中,對執行網路操作的函數(如 Send 和 Receive)的調用一直等到操作完成後才將控制返回給調用程式。在非同步模式中,這些調用立即返回。

建立通訊端


在可以使用通訊端與遠程裝置通訊之前,必須使用協議和網路地址資訊初始化通訊端。Socket 類的建構函式具有指定通訊端用來建立串連的地址族、通訊端類型和協議類型的參數。下面的樣本建立一個 Socket,它可用於在基於 TCP/IP 的網路(如 Internet)上通訊。
 [C#]
Socket s = new Socket(AddressFamily.InterNetwork, 
  SocketType.Stream, ProtocolType.Tcp);

若要使用 UDP 而不是 TCP,請更改協議類型,如下面的樣本所示。
 [C#]
Socket s = new Socket(AddressFamily.InterNetwork, 
  SocketType.Dgram, ProtocolType.Udp);

AddressFamily 枚舉指定 Socket 類用來解析網路地址的標準地址族(例如, AddressFamily.InterNetwork 成員指定 IP 版本 4 地址族)。
SocketType 枚舉指定通訊端的類型(例如, SocketType.Stream 成員指示一個用於通過流量控制發送和接收資料的標準通訊端)。
ProtocolType 枚舉指定在 Socket 上通訊時使用的網路通訊協定(例如, ProtocolType.Tcp 指示通訊端使用 TCP; ProtocolType.Udp 指示通訊端使用 UDP)。
建立 Socket 後,它既可以初始化與遠程終結點的串連,也可以接收來自遠程裝置的串連。

使用用戶端通訊端


在可以通過 Socket 初始化對話之前,必須在應用程式和遠程裝置之間建立一個資料管道。儘管存在其他網路地址族和協議,但本樣本說明如何建立與遠程服務的 TCP/IP 串連。
TCP/IP 使用一個網路地址和一個服務連接埠號碼來唯一標識裝置。網路地址標識網路上的特定裝置;連接埠號碼標識要串連到的該裝置上的特定服務。網路地址和服務連接埠的組合稱為終結點,它在 .NET 架構中由 EndPoint 類表示。為每個受支援的地址族定義了 EndPoint 的子代;對於 IP 位址族,該類為 IPEndPoint。
Dns 類向使用 TCP/IP 網際網路服務的應用程式提供網域名稱服務 (DNS)。Resolve 方法查詢 DNS 伺服器以將方便使用的網域名稱(如“host.contoso.com”)映射到數字形式的 網際網路位址(如 192.168.1.1)。 Resolve 返回一個 IPHostEnty 執行個體,該執行個體包含所請求名稱的地址和別名的列表。大多數情況下,可以使用 AddressList 數組中返回的第一個地址。下面的代碼擷取一個 IPAddress 執行個體,該執行個體包含伺服器 host.contoso.com 的 IP 位址。
 [C#]
IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];

Internet 分配號碼機構 (Internet Assigned Numbers Authority, IANA) 定義公用服務的連接埠號碼(有關更多資訊,請訪問 http://www.iana.org/assignments/port-numbers)。其他服務可以具有在 1,024 到 65,535 範圍內的註冊連接埠號碼。下面的代碼將 host.contoso.com 的 IP 位址與連接埠號碼組合,以便為串連建立遠程終結點。
 [C#]
IPEndPoint ipe = new IPEndPoint(ipAddress,11000);

確定了遠程裝置的地址並選擇了用於串連的連接埠後,應用程式可以嘗試建立與遠程裝置的串連。下面的樣本使用現有的 IPEndPoint 執行個體與遠程裝置串連,並捕獲引發的任何異常。
 [C#]
try {
  s.Connect(ipe);
} catch(ArgumentNullException ae) {
  Console.WriteLine("ArgumentNullException : {0}", ae.ToString());
} catch(SocketException se) {
  Console.WriteLine("SocketException : {0}", se.ToString());
} catch(Exception e) {
  Console.WriteLine("Unexpected exception : {0}", e.ToString());
}

使用同步用戶端通訊端


同步用戶端通訊端在等待網路操作完成時掛起應用程式。同步通訊端不適用於在操作中大量使用網路的應用程式,但它們可以為其他應用程式啟用對網路服務的簡單訪問。
若要發送資料,請將位元組數組傳遞到 Socket 類的資料發送方法(Send 和 SendTo)之一。下面的樣本使用 Encoding.ASCII 屬性將字串編碼到位元組數組緩衝區中,然後使用 Send 方法將該緩衝區傳輸到網路裝置。 Send 方法返回傳送到網路裝置的位元組數。
 [C#]
byte[] msg = System.Text.Encoding.ASCII.GetBytes("This is a test");
int bytesSent = s.Send(msg);

Send 方法從緩衝區中移除位元組,並用網路介面將這些位元組排隊以便發送到網路裝置。網路介面可能不會立即發送資料,但它最終是會發送的,只要串連是用 Shutdown 方法正常關閉的。
若要接收來自網路裝置的資料,請將緩衝區傳遞到 Socket 類的資料接收方法(Receive 和 ReceiveFrom)之一。同步通訊端將掛起應用程式,直到從網路接收位元組或者通訊端關閉為止。下面的樣本接收來自網路的資料,然後將其顯示在控制台上。該樣本假定來自網路的資料是用 ASCII 編碼的文本。 Receive 方法返回從網路接收的位元組數。
 [C#]
byte[] bytes = new byte[1024];
int bytesRec = s.Receive(bytes);
Console.WriteLine("Echoed text = {0}",
  System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec));

不再需要通訊端時需要釋放它,具體方法是調用 Shutdown 方法,然後調用 Close 方法。下面的樣本釋放 Socket。SocketShutdown 枚舉定義常數以指示是關閉用於發送的通訊端、用於接收的通訊端還是用於兩者的通訊端。
 [C#]
s.Shutdown(SocketShutdown.Both);
s.Close();


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.