.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 如下所示:

csharp 复制代码
<?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 文件如下所示:

csharp 复制代码
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 如下所示:

csharp 复制代码
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、主界面添加跳转按钮

csharp 复制代码
<?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 &#10;.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、主界面后台代码

csharp 复制代码
  private async void navigateBtn_Clicked(object sender, EventArgs e)
  {
      await Navigation.PushAsync(new Mine()); // 跳转到 Mine界面
  }

至此就实现了一个UDP通信的demo,添加定时器发送是因为我的版本程序需要收到信息才回复一个对应的信息。

6、程序调试效果如下:

相关推荐
bigsea761 小时前
mongoose 支持https踩坑纪实
网络协议·http·https
Bug退退退1232 小时前
UDP报文格式
网络·网络协议·udp
哇哈哈AD钙奶3 小时前
iis强制重定向https
网络协议·http·https
如若1233 小时前
查看代理设置Get-Item Env:https_proxy
网络协议·http·https
codeBrute3 小时前
WebSocket实现分布式的不同方案对比
分布式·websocket·网络协议
三五a4 小时前
源码编译http
网络·网络协议·http
天堂镇的幽灵6 小时前
.net链接mysql简单而高效
android·mysql·.net
2301_795168588 小时前
javascript基础从小白到高手系列一十二:JSON
javascript·udp·json
九州ip动态8 小时前
运营媒体账号为什么需要住宅IP
网络·网络协议·tcp/ip