当前位置: 首页 > article >正文

.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 &#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、主界面后台代码

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

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

6、程序调试效果如下:
在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/506836.html

相关文章:

  • 【PHP】双方接口通信校验服务
  • SpringSecurity详解
  • MySQL NaviCat 安装及配置教程(Windows)【安装】
  • docker 部署 MantisBT
  • c#删除文件和目录到回收站
  • 一次完整的tcpdump -XX输出报文详解
  • 华为手机改ip地址能改定位吗
  • [操作系统] 深入理解操作系统的概念及定位
  • 阻塞赋值和非阻塞赋值
  • 初学stm32 --- CAN
  • 在 pom.xml 文件中指定 repositories
  • 论文高级GPT指令推荐
  • HTML学习笔记记录---速预CSS(2) 复合属性、盒子模型、边框线、浮动、定位
  • 50.【8】BUUCTF WEB HardSql
  • knowledge-vue监听传入值变化请求后端数据更新
  • 如何在linux系统上完成定时开机和更新github端口的任务
  • springboot 项目配置https
  • Rust 零大小类型(ZST)
  • 【设计模式-结构型】装饰器模式
  • C++ union 联合(八股总结)
  • 微调神经机器翻译模型全流程
  • 紫光无人机AI飞控平台介绍
  • Mybatis-Plus:简介、入门案例
  • 【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列
  • 【matlab】matlab知识点及HTTP、TCP通信
  • npm发布工具包+使用