HOWTO · Csharp
在 C# 中設定客戶端-伺服器通訊
一個程式設計教程,解釋如何使用 C# 在 .NET 框架中設定客戶端-伺服器通訊。
本頁內容
這個簡單的程式設計教程將討論客戶端-伺服器環境中的資料傳輸。它還將通過 TCP 套接字程式設計為客戶端-伺服器通訊模型提供基於 C# 的實現。
傳輸控制協議 (TCP)
開放系統互連 (OSI) 是一種廣泛採用的通訊參考模型,它解釋了計算機如何相互通訊。它確保無差錯的資料從一端傳送到另一端。
分層 OSI 模型定義了傳送或接收資料時要遵循的一些規則和協議。所有層都單獨工作,並執行從一端到另一端傳輸資料的任務。
本文將僅解釋傳輸層。該層使用的主要協議是傳輸控制協議(TCP),主要職責如下:
- 在兩端建立連線,然後在通訊結束時銷燬該連線。
- 資料傳輸包括以下任務:
- 確保資料可靠性並檢查資料是否按順序傳輸且無錯誤。
- 檢測錯誤(如果有)並重新傳送丟失的資料包。
- 控制資料包的流量和速率。
- 確認並設定標誌。
在 C# 中設定客戶端-伺服器通訊
讓我們轉向使用 C# 語言在 .NET 框架中實現客戶端/伺服器應用程式。我們將使用 Visual Studio Enterprise Edition 2019 進行此實施。
我們將建立兩個應用程式,一個用於客戶端,一個用於伺服器端。對於測試,這兩個應用程式都將駐留在同一臺計算機上。
首先,我們將建立一個客戶端應用程式。為此,開啟 Visual Studio 並建立一個新專案。
然後,選擇專案型別 Console Application 並單擊 Next。
將專案名稱設為 Client Application,將解決方案名稱設為 ClientServerApplication。這將為客戶端建立一個新專案。
對於伺服器端程式設計,在同一解決方案中建立另一個專案:
這個專案將被命名為 ServerApplication 並且在同一個解決方案中。
建立專案後,你必須新增 Network Comms Dot Net 包檔案。為此,你需要使用 NuGet 控制檯安裝它們。
在影象中像這樣轉到工具> NuGet 包管理器>包管理器控制檯:
你將在視窗中看到包管理器控制檯,如上圖所示。在這個控制檯中,我們將編寫命令:
PM > Install - Package NetworkCommsDotNet - Version 3.0.3
在兩個專案中成功安裝包後,就可以開始編碼了。開啟 ServerApplication 專案並編寫程式碼:
public static void ConnectServer() {
IPHostEntry myhost = Dns.GetHostEntry("localhost");
IPAddress ipAddr = myhost.AddressList[0];
IPEndPoint myEndPoint = new IPEndPoint(ipAddr, 11000);
try {
Socket listenerSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenerSocket.Bind(myEndPoint);
listenerSocket.Listen(5);
Console.WriteLine("Waiting for Client Socket to Coonect...");
Socket socketHandler = listenerSocket.Accept();
// data from the client.
string myData = null;
byte[] dataBytes = null;
while (true) {
dataBytes = new byte[1023];
int bytesRece = socketHandler.Receive(dataBytes);
myData += Encoding.ASCII.GetString(dataBytes, 0, bytesRece);
if (myData.IndexOf("<EOF>") > -1) {
myData = myData.Remove(myData.Length - 5);
break;
}
}
Console.WriteLine("Data Received from Client : {0}", myData);
byte[] msg = Encoding.ASCII.GetBytes("This is the test msg from server");
socketHandler.Send(msg);
socketHandler.Shutdown(SocketShutdown.Both);
socketHandler.Close();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
Console.WriteLine("\n Press any key to continue...");
Console.ReadKey();
}
然後在客戶端,編寫以下程式碼:
public static void ConnectClient() {
byte[] myBytes = new byte[1024];
try {
IPHostEntry myhost = Dns.GetHostEntry("localhost");
IPAddress ipAddr = myhost.AddressList[0];
IPEndPoint clientEP = new IPEndPoint(ipAddr, 11000);
Socket senderSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try {
// Connect to the EndPoint
senderSocket.Connect(clientEP);
Console.WriteLine("Client Connect to Server at {0}", senderSocket.RemoteEndPoint.ToString());
// Convert the string into a byte-type array.
Console.WriteLine("Sending a test message");
byte[] msg = Encoding.ASCII.GetBytes("This is a test message from Client<EOF>");
// Send the data using the socket.
int dataSent = senderSocket.Send(msg);
// Receive the reply from the server device.
int dataRec = senderSocket.Receive(myBytes);
Console.WriteLine("Data Received from Server = {0}",
Encoding.ASCII.GetString(myBytes, 0, dataRec));
// delete the socket
senderSocket.Shutdown(SocketShutdown.Both);
senderSocket.Close();
Console.ReadKey();
} catch (ArgumentNullException ane) {
Console.WriteLine(ane.ToString());
} catch (SocketException se) {
Console.WriteLine(se.ToString());
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
在對應專案的 main 函式中呼叫這些函式後,需要構建專案,也可以構建整個解決方案。然後,為了執行輸出,導航到這些專案的檔案資源管理器並執行兩者的 exe 檔案。
收到以下輸出: