在 C# 中创建一个 UDP 服务器
本文将展示如何在 C# 中创建一个简单的 UDP 服务器。
在 C#
中创建一个 UDP 服务器
简单介绍一下背景,UDP 协议不需要与客户端建立连接。数据只是传输而不验证客户端是否接收到它。
这种类型的协议通常用于广播数据。由于 UDP 是无连接的,因此侦听器无需在线即可接收消息。
要使用 UDP 传输数据报,你需要知道托管服务的网络设备的网络地址和服务的 UDP 端口号。流行服务的端口号由 Internet 号码分配机构 (IANA) 定义;端口号的范围是 1,024 到 65,535,可以分配给不在 IANA 列表中的服务。
在基于 IP 的网络上,特殊的网络地址用于处理 UDP 广播消息。以下解释以 Internet 的 IP 版本 4 地址族为例。
通过设置主机标识的所有位,可以将广播定向到网络的指定部分。使用地址 192.168.1.255 向网络上所有 IP 地址以 192.168.1 开头的主机广播。
我们现在准备建立或创建一个套接字,设置我们的 UDP 协议,并立即开始通信。
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
这些将是用于设置服务器的库。这些库支持与网络相关的所有基本功能,例如构建套接字、处理 IPV4 地址等等。
public class SimpleUdpSrvr {
public static void Main() {
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
}
int recv
行创建一个整数类型的 recv
变量,其中包含客户端收到的字符串消息的字节数。
byte[] data = new byte[1024];
line 用于为每个包含 1024 个单元格的单元格创建一个名为 data
的字节大小的数组,也称为数组大小。该数组是在堆中动态创建的。
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
行告诉它为套接字创建一个 ipep
变量。传入的信息告诉它应该使用什么样的套接字。
IPEndPoint
类表示具有 IP 地址和端口号的网络端点;客户端需要此配置信息来连接我们的服务。传入的 IPAddress.Any
参数告诉服务器可以使用任何 IP 地址连接到 9050 端口号; ipep
变量也是动态创建的。
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
这一行创建了一个 newsock
变量,一个我们将通过它进行通信的套接字。传入的参数告诉我们要创建什么样的套接字。
AddressFamily.InterNetwork
告诉我们我们需要本地 IP 地址。SocketType.Dgram
参数指出数据应该以数据报而不是数据包的形式流动。
最后,ProtocolType.Udp
参数告诉我们将使用的套接字的协议类型。现在,我们的套接字已创建。
newsock.Bind(ipep);
Console.WriteLine("Waiting for a client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
到目前为止,我们已经在网络中创建了一个端点,以及一个用于通信的套接字,newsock.Bind(ipep);
line 现在将帮助我们将端点绑定到套接字。
ipep
是一个变量,它包含关于我们端点的信息,并在我们的 newsock
对象的 bind()
函数中传递。
Console.WriteLine("Waiting for a client...");
此行在屏幕上打印服务器正在等待客户端发送任何消息。我们需要为将尝试与服务器通信的发送方创建另一个端点。
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
这一行创建了另一个端点,变量称为 sender
。在它的 IPAddress.Any
中传递的参数告诉我们期待任何 IP 地址,而 0
意味着它是端口号的通配符,系统应该看到并找到任何合适的端口分配给我们。
EndPoint Remote = (EndPoint)(sender);
行用于查找发送者的 IP 地址并将其存储在 remote
变量中。
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
我们在程序开始时创建的 recv
变量现在用于 recv = newsock.ReceiveFrom(data, ref Remote);
线。我们使用之前创建的套接字 newsock
的 Receive()
函数,并且当前接收我们当时在套接字中的所有数据。
传递 Receive()
函数的参数告诉在哪里存储数据以及应该存储或预期谁的数据。data
参数是被传递的字节大小数组,数据将被写入数据数组。
ref Remote
参数告诉 IP 地址发送了数据,该函数将返回从该套接字获取的字节数并将其存储到 recv
变量中。
Console.WriteLine("Message received from {0}:", Remote.ToString());
此行在屏幕上写入通过套接字发送数据的客户端的 IP 地址。传递的参数 Remote.ToString()
将十进制数字转换为 ASCII 字符,而 remote
变量是引用客户端的第二个端点。
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
这一行将实际数据写入屏幕。通过套接字发送的数据为原始形式,应转换为 ASCII 字符才能读取。
Encoding.ASCII.GetString(data, 0, recv)
行从作为参数传递的 data
变量中获取数据,recv
参数(包含客户端发送的字节数)告诉从屏幕上的 data
变量中写入这么多字节。
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
string welcome = "欢迎来到我的测试服务器";
行用欢迎来到我的测试服务器
文本初始化欢迎
字符串变量。
data = Encoding.ASCII.GetBytes(welcome);
line 将 welcome
变量作为 Encoding.ASCII.GetBytes()
函数中的参数并将其转换为原始形式,以便准备好通过另一端的套接字发送。
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
这一行通过我们之前创建的套接字 newsock
发送数据并使用 Send()
函数。它需要的参数是:包含要发送的原始数据形式的 data
变量,data.Length
参数告诉在套接字上写入多少字节,因为数据的长度等于字节数, SocketFlags.None
参数告诉我们将所有标志保持为零,标志是指示符,每个标志都有其含义。
Remote
变量参数告诉我们要将数据发送到的客户端,因为 Remote
变量存储客户端的 IP 地址和端口号。
while (true) {
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
while(true)
行表明它是一个无限循环,并且它的所有语句都将无限运行。数据 = 新字节 [1024];
行在执行时创建一个长度为 1024 的新字节大小数组。
recv = newsock.ReceiveFrom(data, ref Remote);
line 从客户端接收数据并将其保存到数据数组中。
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
将数据写入屏幕。
newsock.SendTo(data, recv, SocketFlags.None, Remote);
行将服务器从它收到的相同数据发送回客户端。
之后,服务器将再次停止并等待客户端,客户端发送给服务器的任何内容都会以相同的消息进行响应。该服务器将永远不会终止,除非它崩溃或用户手动停止它。
现在,当我们学习了如何在 C# 中创建 UDP 服务器及其基本功能后,我们可以添加更多功能并根据我们的要求制作服务器。
完整的源代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SimpleUdpSrvr {
public static void Main() {
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
Console.WriteLine("Waiting for a client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
while (true) {
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
}
}
相关文章
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:198 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:171 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中将 List<string>转换为字符串
发布时间:2024/03/16 浏览次数:187 分类:编程语言
-
在 C# 中,有两种主要方法可用于将 List
转换为字符串变量,Linq 方法和 String.Join()函数。
在 C# 中发出 HTTP POST Web 请求
发布时间:2024/02/04 浏览次数:131 分类:编程语言
-
在 C# 中,可以使用 3 种主要方法来发出 HTTP POST Web 请求:WebClient 类,HttpWebRequest 类和 HttpClient 类。本教程将讨论在 C# 中发出 HTTP POST Web 请求的方法。使用 C# 中的 WebClient 类发出 HTTP POST Web 请求
在 C# 中运行命令提示符命令
发布时间:2024/02/04 浏览次数:130 分类:编程语言
-
Process 类可用于在 C# 中运行命令提示符命令。在 C# 中使用 Process.Start() 函数运行命令提示符命令
在 C# 中调整图像大小
发布时间:2024/02/04 浏览次数:203 分类:编程语言
-
有两种主要方法可用于在 C# 中调整图像的大小,Bitmap 类构造函数和 graphics.DrawImage()函数。在本教程中,我们将讨论在C#中调整图像大小的方法。我们将带您完成整个过程,从加载原始图像到保
在 C# 中下载图片
发布时间:2024/02/04 浏览次数:138 分类:编程语言
-
有 3 种主要方法可用于下载 C# 中的图片,WebClient.DownloadFile()函数,Bitmap 类和 Image.FromStream()函数。在 C# 中使用 WebClient 类下载图片 WebClient 类提供了用于向 C# 中的 URL 发送数据和从 URL 接收数据
在 C# 中使用秒表
发布时间:2024/02/04 浏览次数:139 分类:编程语言
-
我们可以使用 Stopwatch 类来计算 C# 中的经过时间。使用 C# 中的秒表类计算经过时间 Stopwatch 类在 C# 中准确测量经过的时间。
在 C# 中获取可执行路径
发布时间:2024/02/04 浏览次数:200 分类:编程语言
-
有 3 种主要方法可用于获取 C# 中程序的可执行路径,即 Assembly 类,AppDomain 类和 Path 类。本教程将介绍获取 C# 代码的可执行路径的方法。使用 C# 中的 Assembly 类获取可执行路径