.NET MAUI进行UDP通信
.NET MAUI是一个开源的跨平台框架库。NET,使创建丰富、现代的用户界面变得容易,.NET MAUI提供了一个多平台应用程序UI。我们可以使用.NET MAUI,用于使用C#和XAML创建本地移动和桌面应用程序。它还支持XAML热重载,这意味着我们可以在运行时编辑代码。NET MAUI应用程序可以在任何机器上运行,如windows或android模拟器。
打开Visual Studio
打开visual studio并单击“创建新项目”按钮。接下来,在搜索栏中,搜索.NET MAUI
接着一直点击下一步即可,直到创建项目。
1、添加新的page页:MinePage.xaml 如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm ="clr-namespace:MauiAppDemo.VM"
x:Class="MauiAppDemo.Page.Mine"
Title="Mine">
<ContentPage.BindingContext>
<vm:UdpViewModel /> //绑定上下文内容
</ContentPage.BindingContext>
<VerticalStackLayout >
<Label
Text="Welcome to .NET MAUI!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Label Text="接收到的消息:" FontSize="20" />
<ScrollView
x:Name="MessageScrollView"
HeightRequest="100"
VerticalScrollBarVisibility="Default">
<Label
x:Name="ReceivedMessageLabel"
Text="{Binding ReceivedMessage}"
FontSize="18"
TextColor="Red"
LineBreakMode="WordWrap" />
</ScrollView>
<Entry x:Name="MessageEntry" Placeholder="Enter message to send" />
<Button
Text="Start Sending"
WidthRequest="200"
Margin="10,20,10,0"
HorizontalOptions="Center"
Style="{StaticResource Button}"
Clicked="OnStartSendingClicked" />
<Button Text="Stop Sending"
WidthRequest="200"
Margin="10,20,10,0"
HorizontalOptions="Center"
Style="{StaticResource Button}"
Clicked="OnStopSendingClicked" />
<Button
Text="连接"
WidthRequest="200"
Margin="10,20,10,0"
x:Name="connectBtn"
IsVisible="False"
HorizontalOptions="Center"
Style="{StaticResource Button}"
Clicked="connectBtn_Clicked">
</Button>
<Button
Text="Reback"
WidthRequest="200"
Margin="10,20,10,0"
x:Name="backBtn"
HorizontalOptions="Center"
Style="{StaticResource Button}"
Clicked="backBtn_Clicked">
</Button>
</VerticalStackLayout>
</ContentPage>
2、文件中使用了 VM,故添加 UdpViewModel.cs 文件如下所示:
using MauiAppDemo.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MauiAppDemo.VM
{
/// <summary>
/// udp消息接收类
/// </summary>
public class UdpViewModel : INotifyPropertyChanged
{
private string _receivedMessage=string.Empty;
public string ReceivedMessage
{
get => _receivedMessage;
set
{
if (_receivedMessage != value)
{
_receivedMessage = value;
OnPropertyChanged();
}
}
}
private Timer _timer;
private readonly string _targetIp = "10.10.100.100";
private readonly int _targetPort = 8899;
//开始发送信息
public void StartSending(string message, double intervalMs)
{
StopSending(); // 确保只有一个定时器运行
_timer = new Timer(async _ =>
{
await UDPHelper.Instance.SendMessageAsync(message, _targetIp, _targetPort);
}, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(intervalMs));
}
public void StopSending()
{
_timer?.Dispose();
_timer = null;
}
//开始接收信息
public void StartReceiving()
{
Task.Run(async () =>
{
while (true)
{
string receivedMessage = await UDPHelper.Instance.ReceiveMessageAsync();
if (!string.IsNullOrEmpty(receivedMessage))
{
MainThread.BeginInvokeOnMainThread(() =>
{
ReceivedMessage += receivedMessage;
});
}
}
});
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3、添加UDP帮助类:UDPHelper.cs 如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MauiAppDemo.Common
{
/// <summary>
/// udp帮助类
/// </summary>
public class UDPHelper
{
private static readonly Lazy<UDPHelper> _instance = new(() => new UDPHelper());
private static readonly object _lock = new(); // 用于线程安全的锁
private UdpClient _udpClient;
private CancellationTokenSource _cancellationTokenSource;
private int _port;
// 单例模式,构造函数设为私有
private UDPHelper()
{
// 初始化 UdpClient,不绑定端口以支持发送
_udpClient = new UdpClient();
}
// 获取单例实例
public static UDPHelper Instance => _instance.Value;
// 设置监听端口
public void Initialize(int port)
{
lock (_lock)
{
_port = port;
// 关闭之前的客户端(如果存在),并重新初始化
_udpClient?.Close();
_udpClient = new UdpClient(_port);
}
}
// 发送消息(线程安全)
public async Task SendMessageAsync(string message, string ipAddress, int port)
{
byte[] data = Encoding.UTF8.GetBytes(message);
await _udpClient.SendAsync(data, data.Length, ipAddress, port);
}
// 接收消息(线程安全)
public async Task<string> ReceiveMessageAsync()
{
try
{
var result = await _udpClient.ReceiveAsync();
return Encoding.UTF8.GetString(result.Buffer);
}
catch (Exception ex)
{
// 打印错误日志以检查问题
Console.WriteLine($"接收消息时出错: {ex.Message}");
return string.Empty;
}
}
public void StopReceiving()
{
_cancellationTokenSource?.Cancel();
_udpClient?.Close();
_udpClient = null;
}
}
}
4、主界面添加跳转按钮
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppDemo.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a race car number eight" />
<Label
Text="Hello, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to .NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
<Button
x:Name="navigateBtn"
Text="Goto another page"
SemanticProperties.Hint="goto another page when you click"
Clicked="navigateBtn_Clicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
5、主界面后台代码
private async void navigateBtn_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Mine()); // 跳转到 Mine界面
}
至此就实现了一个UDP通信的demo,添加定时器发送是因为我的版本程序需要收到信息才回复一个对应的信息。
6、程序调试效果如下: