当我们需要进行大量的网络IO操作时,使用异步编程可以大大提高程序的效率和性能。在C#中,我们可以使用async和await关键字来进行异步编程。
具体地,当我们进行UDP通讯时,可以将接收和发送操作都用异步的方法来进行,并且使用await关键字来等待异步操作完成。下面我们来看一个实现异步UDP通讯的示例代码。
步骤一:创建UdpClient对象
在C#中,我们可以使用UdpClient类来进行UDP通讯。在使用UdpClient类之前,我们需要首先创建一个UdpClient对象。下面是一个创建UdpClient对象的示例代码:
UdpClient udpClient = new UdpClient();
步骤二:异步接收UDP消息
在接收UDP消息时,我们通常需要不断地等待,并且在等待期间程序需要继续执行其他的操作。因此,我们可以使用异步的方法来接收UDP消息。下面是一个异步接收UDP消息的示例代码:
private async Task ReceiveAsync()
{
while (true)
{
UdpReceiveResult result = await udpClient.ReceiveAsync();
byte[] data = result.Buffer;
// 处理UDP消息
}
}
在上面的代码中,我们使用了一个无限循环,不断地等待接收UDP消息。在每次接收到UDP消息时,我们使用await关键字等待异步操作完成,然后获取接收到的数据,并对数据进行处理。
步骤三:异步发送UDP消息
在发送UDP消息时,我们也可以使用异步方法来进行。下面是一个异步发送UDP消息的示例代码:
private async Task SendAsync(string message, IPAddress address, int port)
{
byte[] data = Encoding.UTF8.GetBytes(message);
await udpClient.SendAsync(data, data.Length, address.ToString(), port);
}
在上面的代码中,我们使用Encoding.UTF8.GetBytes()方法将字符串转换为字节数组,然后使用await关键字等待异步发送操作完成。
步骤四:启动异步UDP通讯
在创建了UdpClient对象并定义了异步接收和发送数据的方法之后,我们就可以启动异步UDP通讯了。下面是一个启动异步UDP通讯的示例代码:
private async void Start(string ipAddress, int port)
{
udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(ipAddress), port));
await ReceiveAsync();
}
在上面的代码中,我们首先创建了一个UdpClient对象,并将监听的IP地址和端口号传递给构造函数。然后使用await关键字等待异步接收UDP消息的操作完成,这样程序就可以开始异步接收UDP消息了。
示例说明一:使用异步UDP通讯实现简单的聊天程序
下面是一个使用异步UDP通讯实现简单的聊天程序的示例代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace AsyncUdpDemo
{
class Program
{
private static UdpClient udpClient = new UdpClient();
static async Task Main(string[] args)
{
Console.Write("请输入监听的IP地址:");
string ipAddress = Console.ReadLine();
Console.Write("请输入监听的端口号:");
int port = int.Parse(Console.ReadLine());
udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(ipAddress), port));
Console.WriteLine($"已启动监听程序,监听地址为 {ipAddress}:{port}");
Console.WriteLine();
Task receiveTask = ReceiveAsync();
while (true)
{
Console.Write("请输入要发送的消息:");
string message = Console.ReadLine();
await SendAsync(message, IPAddress.Broadcast, port);
}
}
private static async Task ReceiveAsync()
{
while (true)
{
UdpReceiveResult result = await udpClient.ReceiveAsync();
byte[] data = result.Buffer;
string message = Encoding.UTF8.GetString(data);
Console.WriteLine($"{result.RemoteEndPoint.Address}: {message}");
}
}
private static async Task SendAsync(string message, IPAddress address, int port)
{
byte[] data = Encoding.UTF8.GetBytes(message);
await udpClient.SendAsync(data, data.Length, address.ToString(), port);
}
}
}
在上面的代码中,我们首先创建了一个UdpClient对象,并使用await关键字异步接收UDP消息。然后在while循环中,不断地等待输入要发送的消息,并使用await关键字异步发送UDP消息。在接收到UDP消息时,我们将消息内容输出到控制台。
示例说明二:使用异步UDP通讯实现简单的文件传输程序
下面是一个使用异步UDP通讯实现简单的文件传输程序的示例代码:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace AsyncUdpDemo
{
class Program
{
private static UdpClient udpClient = new UdpClient();
private static FileStream fileStream = null;
private static int packageSize = 1024 * 1024;
private static byte[] packageBuffer = new byte[packageSize];
private static int currentPackageIndex = 0;
private static bool isTransfering = false;
static async Task Main(string[] args)
{
Console.Write("请输入监听的IP地址:");
string ipAddress = Console.ReadLine();
Console.Write("请输入监听的端口号:");
int port = int.Parse(Console.ReadLine());
udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(ipAddress), port));
Console.WriteLine($"已启动监听程序,监听地址为 {ipAddress}:{port}");
Console.WriteLine();
Task receiveTask = ReceiveAsync();
while (true)
{
Console.Write("请输入要发送的文件路径:");
string filePath = Console.ReadLine();
if (isTransfering)
{
Console.WriteLine("正在传输文件,请稍后再试");
continue;
}
if (!File.Exists(filePath))
{
Console.WriteLine("文件不存在,请重新输入");
continue;
}
fileStream = new FileStream(filePath, FileMode.Open);
int fileNameLength = Encoding.UTF8.GetByteCount(Path.GetFileName(filePath));
byte[] fileNameData = new byte[fileNameLength + 4];
byte[] fileNameLengthData = BitConverter.GetBytes(fileNameLength);
Array.Copy(fileNameLengthData, fileNameData, 4);
Encoding.UTF8.GetBytes(Path.GetFileName(filePath)).CopyTo(fileNameData, 4);
await SendAsync(fileNameData, fileNameData.Length, IPAddress.Broadcast, port);
isTransfering = true;
Console.WriteLine("开始传输文件,请等待...");
while (currentPackageIndex < fileStream.Length)
{
int bytesRead = await fileStream.ReadAsync(packageBuffer, 0, packageSize);
byte[] packageData = new byte[bytesRead];
Array.Copy(packageBuffer, packageData, bytesRead);
await SendAsync(packageData, packageData.Length, IPAddress.Broadcast, port);
currentPackageIndex += bytesRead;
Console.Write($"\r已传输 {(float)currentPackageIndex / fileStream.Length:P}");
}
fileStream.Close();
isTransfering = false;
Console.WriteLine();
Console.WriteLine("文件传输完毕,请查收");
}
}
private static async Task ReceiveAsync()
{
while (true)
{
UdpReceiveResult result = await udpClient.ReceiveAsync();
byte[] data = result.Buffer;
if (fileStream == null)
{
string message = Encoding.UTF8.GetString(data);
Console.WriteLine($"{result.RemoteEndPoint.Address}: {message}");
}
else
{
if (currentPackageIndex < fileStream.Length)
{
byte[] packageSizeData = new byte[4];
Array.Copy(data, 0, packageSizeData, 0, 4);
int packageSize = BitConverter.ToInt32(packageSizeData);
byte[] packageData = new byte[packageSize];
Array.Copy(data, 4, packageData, 0, packageSize);
await fileStream.WriteAsync(packageData, 0, packageSize);
Console.Write($"\r已接收 {(float)currentPackageIndex / fileStream.Length:P}");
}
}
}
}
private static async Task SendAsync(byte[] data, int length, IPAddress address, int port)
{
await udpClient.SendAsync(data, length, address.ToString(), port);
}
}
}
在上面的代码中,我们使用异步UDP通讯来实现文件传输功能。在发送文件时,我们将文件名和文件内容分开发送,以便接收端能够正确解析文件内容。在接收到文件名时,我们使用FileStream对象来创建文件,并将isTransfering标记设置为true,表示文件正在传输中。在接收到文件内容时,我们将内容写入FileStream对象中,并输出当前传输进度。在传输完成之后,我们将FileStream对象关闭,并将isTransfering标记设置为false,表示文件传输已经完成。在接收消息时,如果isTransfering标记为false,表示接收到的是普通消息,将其内容输出到控制台。如果isTransfering标记为true,表示接收到的是文件内容,将其写入FileStream对象中,并输出当前接收进度。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中使用async和await实现异步Udp通讯的示例代码 - Python技术站