相关文章推荐
欢快的四季豆  ·  ASP.NET Core MVC ...·  1 周前    · 
潇洒的茴香  ·  virtual box ...·  2 月前    · 
谦虚好学的脸盆  ·  Cognos Business ...·  1 年前    · 

在您使用通訊端與遠端裝置進行通訊之前,必須先使用通訊協定和網路位址資訊初始化通訊端。 Socket 類別的建構函式所擁有的參數,可指定通訊端用來建立連線的位址家族、通訊端類型和通訊協定類型。 將用戶端通訊端連線到伺服器通訊端時,用戶端會使用 IPEndPoint 物件來指定伺服器的網路位址。

建立 IP 端點

使用 System.Net.Sockets 時,您會將網路端點表示為 IPEndPoint 物件。 IPEndPoint 是以 IPAddress 及其對應的連接埠號碼來建構。 在透過 Socket 起始交談之前,您要先建立應用程式和遠端目的地之間的資料管道。

TCP/IP 會使用網路位址和服務連接埠編號來唯一識別服務。 網路位址可識別特定網路目的地;連接埠號碼則可識別該裝置上要連線的特定服務。 網路位址和服務連接埠的組合稱為端點,在 .NET 中是以 EndPoint 類別表示。 每個支援的位址系列已定義 EndPoint 的子系;對於 IP 位址系列,此類別是 IPEndPoint

Dns 類別會提供網域名稱服務給使用 TCP/IP 網際網路服務的應用程式。 GetHostEntryAsync 方法會查詢 DNS 伺服器,以將使用者易記的網域名稱 (例如 "host.contoso.com") 對應到數字的網際網路位址 (例如 192.168.1.1 )。 GetHostEntryAsync 會傳回 Task<IPHostEntry> ,在等待時其中包含位址和所要求名稱之別名的清單。 在大部分情況下,您可以使用 AddressList 陣列中傳回的第一個位址。 下列程式碼可取得包含伺服器 host.contoso.com 之 IP 位址的 IPAddress

IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync("host.contoso.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];

針對手動測試和偵錯目的,您通常可以使用 GetHostEntryAsync 方法以及從 Dns.GetHostName() 值取得的結果主機名稱,將 localhost 名稱解析為 IP 位址。 請考慮下列程式碼片段:

var hostName = Dns.GetHostName();
IPHostEntry localhost = await Dns.GetHostEntryAsync(hostName);
// This is the IP address of the local machine
IPAddress localIpAddress = localhost.AddressList[0];

Internet Assigned Numbers Authority (IANA) 定義了通用服務的連接埠號碼。 如需詳細資訊,請參閱 IANA:服務名稱和傳輸通訊協定連接埠號碼登錄)。 其他服務的已登錄連接埠編號範圍可以是 1,024 到 65,535。 下列程式碼會合併 host.contoso.com 的 IP 位址與連接埠號碼,以建立連線的遠端端點。

IPEndPoint ipEndPoint = new(ipAddress, 11_000);

在判斷遠端裝置的位址並選擇要用於連線的連接埠之後,應用程式可以建立與遠端裝置的連線。

建立 Socket 用戶端

建立 endPoint 物件之後,建立用戶端通訊端以連線到伺服器。 連線通訊端之後,就可以從伺服器通訊端連線傳送和接收資料。

using Socket client = new( ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); await client.ConnectAsync(ipEndPoint); while (true) // Send message. var message = "Hi friends 👋!<|EOM|>"; var messageBytes = Encoding.UTF8.GetBytes(message); _ = await client.SendAsync(messageBytes, SocketFlags.None); Console.WriteLine($"Socket client sent message: \"{message}\""); // Receive ack. var buffer = new byte[1_024]; var received = await client.ReceiveAsync(buffer, SocketFlags.None); var response = Encoding.UTF8.GetString(buffer, 0, received); if (response == "<|ACK|>") Console.WriteLine( $"Socket client received acknowledgment: \"{response}\""); break; // Sample output: // Socket client sent message: "Hi friends 👋!<|EOM|>" // Socket client received acknowledgment: "<|ACK|>" client.Shutdown(SocketShutdown.Both);

在上述 C# 程式碼中:

  • 具現化具有指定 endPoint 執行個體位址系列、SocketType.Stream、和 ProtocolType.Tcp 的新 Socket 物件。

  • 使用 endPoint 執行個體作為引數呼叫 Socket.ConnectAsync 方法。

  • while 迴圈中:

  • 使用 Socket.SendAsync 將訊息編碼並傳送至伺服器。
  • 將傳送的訊息寫入主控台。
  • 使用 Socket.ReceiveAsync 初始化緩衝區以接收來自伺服器的資料。
  • response 是通知時,會寫入主控台並結束迴圈。
  • 最後,client 會呼叫 Socket.Shutdown 指定 SocketShutdown.Both,這會關閉傳送和接收作業。

    建立 Socket 伺服器

    若要建立伺服器通訊端,endPoint 物件可以在任何 IP 位址上接聽連入連線,但必須指定連接埠號碼。 建立通訊端之後,伺服器就可以接受連入連線,並與用戶端通訊。

    using Socket listener = new( ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listener.Bind(ipEndPoint); listener.Listen(100); var handler = await listener.AcceptAsync(); while (true) // Receive message. var buffer = new byte[1_024]; var received = await handler.ReceiveAsync(buffer, SocketFlags.None); var response = Encoding.UTF8.GetString(buffer, 0, received); var eom = "<|EOM|>"; if (response.IndexOf(eom) > -1 /* is end of message */) Console.WriteLine( $"Socket server received message: \"{response.Replace(eom, "")}\""); var ackMessage = "<|ACK|>"; var echoBytes = Encoding.UTF8.GetBytes(ackMessage); await handler.SendAsync(echoBytes, 0); Console.WriteLine( $"Socket server sent acknowledgment: \"{ackMessage}\""); break; // Sample output: // Socket server received message: "Hi friends 👋!" // Socket server sent acknowledgment: "<|ACK|>"

    在上述 C# 程式碼中:

  • 具現化具有指定 endPoint 執行個體位址系列、SocketType.Stream、和 ProtocolType.Tcp 的新 Socket 物件。

  • listener 會使用 endPoint 執行個體作為引數來呼叫 Socket.Bind 方法,以將通訊端與網路位址產生關聯。

  • 系統會呼叫 Socket.Listen() 方法來接聽連入連線。

  • listener 會呼叫 Socket.AcceptAsync 方法來接受 handler 通訊端上的連入連線。

  • while 迴圈中:

  • 呼叫 Socket.ReceiveAsync 以接收用戶端的資料。
  • 收到資料時,會解碼並寫入主控台。
  • 如果 response 訊息結尾為 <|EOM|>,則會使用 Socket.SendAsync 將通知傳送至用戶端。
  • 執行範例用戶端和伺服器

    先啟動伺服器應用程式,然後啟動用戶端應用程式。

    dotnet run --project socket-server
    Socket server starting...
    Found: 172.23.64.1 available on port 9000.
    Socket server received message: "Hi friends 👋!"
    Socket server sent acknowledgment: "<|ACK|>"
    Press ENTER to continue...
    

    用戶端應用程式會將訊息傳送至伺服器,而伺服器會以通知回應。

    dotnet run --project socket-client
    Socket client starting...
    Found: 172.23.64.1 available on port 9000.
    Socket client sent message: "Hi friends 👋!<|EOM|>"
    Socket client received acknowledgment: "<|ACK|>"
    Press ENTER to continue...
    
  • .NET 中的通訊端
  • .NET 中的網路功能
  • System.Net.Sockets
  • Socket
  • 即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:https://aka.ms/ContentUserFeedback

    提交並檢視相關的意見反應