在 C# 中设置客户端-服务器通信
这个简单的编程教程将讨论客户端-服务器环境中的数据传输。它还将通过 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
文件。
收到以下输出:
Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.
LinkedIn