在您使用套接字與遠端裝置通訊之前,必須先以通訊協定和網路位址資訊初始化套接字。
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 陣列中傳回的第一個位址。 下列程式碼可取得包含伺服器 IPAddress 之 IP 位址的 host.contoso.com
。
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# 程式代碼:
具現化具有指定
Socket
實例位址系列、endPoint
、 和 SocketType.Stream的新 ProtocolType.Tcp 物件。呼叫Socket.ConnectAsync方法並以
endPoint
實例作為參數。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# 程式代碼:
具現化具有指定
Socket
實例位址系列、endPoint
、 和 SocketType.Stream的新 ProtocolType.Tcp 物件。使用
listener
呼叫 Socket.Bind 方法,將endPoint
實例作為參數,以將套接字與網路位址產生關聯。呼叫 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