问题描述
我创建了一个测试 Xamarin.Forms 项目、选项卡式应用程序,支持 iOS、Android 和 UWP.带有样板启动器代码的应用可以在所有 3 个平台上构建并正确运行.
I created a test Xamarin.Forms project, tabbed app, with support for iOS, Android, and UWP. The app with the boilerplate starter code builds and and runs correctly on all 3 platforms.
我尝试在应用中测试接收 UDP 广播.UDP 广播是从同一子网上的另一台机器发送的(已经测试了从另一台机器和同一台机器上的广播,结果是一样的).如果我在这台机器上运行一个独立的、非托管的 UDP 侦听器测试工具(我们内部编写的一个),我可以看到来自另一台机器的所有消息.
Am trying to test receiving UDP broadcast in the app. The UDP broadcast is being sent from another machine on the same subnet (have tested broadcasting from another machine and from the same machine, results are the same). If I run a standalone, unmanaged UDP listener test tool on this machine (one we wrote internally), I can see all the messages coming through from the other machine.
我将代码(如下所示)添加到 Xamarin.Forms 项目并在这台机器上运行了 UWP 构建.我看到的是,在调试输出中,我收到了开始接收"消息,然后没有其他消息.我实际上没有收到消息(或者至少,没有调用回调).我检查了 netstat,可以看到当我的 Xamarin.Forms 应用程序运行时,它绑定到指定的 UDP 端口.但是我的OnUdpDataReceived 永远不会被调用.
I added the code (shown below) to the Xamarin.Forms project and ran the UWP build on this machine. What I'm seeing is that in the debug output I get the "started receiving" message, then nothing else. I'm not actually receiving the messages (or at least, the callback is not being invoked). I checked netstat and can see that when my Xamarin.Forms app is running, it is bound to the specified UDP port. But my OnUdpDataReceived never gets called.
我在解决方案资源管理器中双击了 UWP 项目的 Package.appxmanifest 文件,该文件显示了一个 UI,并在其中选中了功能 >> Internet(客户端& Server)"认为这是权限问题,但这没有帮助.
I double-clicked the UWP project's Package.appxmanifest file in solution explorer which brought up a UI and in that I checked "Capabilities >> Internet (Client & Server)" thinking it was a permissions thing, but this did not help.
编辑:我通过创建两个控制台项目(一个发送方和一个接收方)来验证连接.发送方只是永远循环,每秒发送一个测试 UDP 广播.接收器使用此处显示的相同代码.这些项目按预期工作.因此,相同的接收器代码在控制台项目中有效,但在 Xamarin.Forms 项目中无效.
I verified connectivity by creating two console projects, a sender and a receiver. The sender just loops forever sending a test UDP broadcast each second. The receiver uses the same code shown here. These projects work as expected. So the same receiver code is working in the console project, but not in the Xamarin.Forms project.
首先是一个简单的 UDP 接收器类.
public class BaseUdpReceiver
{
private UdpClient _udpClient;
public BaseUdpReceiver()
{
}
public void Start()
{
_udpClient = new UdpClient()
{
ExclusiveAddressUse = false,
EnableBroadcast = true
};
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, Constants.Network.SOME_CONSTANT_PORT_INTEGER));
_udpClient.BeginReceive(OnUdpDataReceived, _udpClient);
Debug.WriteLine($">>> started receiving");
}
private static void OnUdpDataReceived(IAsyncResult result)
{
Debug.WriteLine($">>> in receive");
var udpClient = result.AsyncState as UdpClient;
if (udpClient == null)
return;
IPEndPoint remoteAddr = null;
var recvBuffer = udpClient.EndReceive(result, ref remoteAddr);
Debug.WriteLine($"MESSAGE FROM: {remoteAddr.Address}:{remoteAddr.Port}, MESSAGE SIZE: {recvBuffer?.Length ?? 0}");
udpClient.BeginReceive(OnUdpDataReceived, udpClient);
}
}
然后是 App.xaml.cs 中使用这个类的代码.
public partial class App : Application
{
private BaseUdpReceiver _udpReceiver;
public App()
{
InitializeComponent();
DependencyService.Register<MockDataStore>();
MainPage = new MainPage();
_udpReceiver = new BaseUdpReceiver();
_udpReceiver.Start();
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
版本信息
Visual Studio 2019 Enterprise v16.4.5
Xamarin 16.4.000.322 (d16-4@ddfd842)
Windows 10 64-bit v1909 (OS Build 18363.657)
Microsoft.NETCore.UniversalWindowsPlatform, v6.2.9
NETStandard.Library, v2.0.3
Xamarin.Essentials, v1.5.0
Xamarin.Forms, v4.5.0.356
推荐答案
在 MS 支持的帮助下使其适用于 UWP 和 Android.
Got it working for both UWP and Android with help from MS support.
请注意,考虑到以下因素,原始帖子中提供的代码是正确且有效的.
- UWP
- 由于 UWP 的网络隔离,您无法在同一台机器上广播和接收,虽然这适用于控制台应用程序,但它不适用于 Xamarin.Forms UWP,所以诀窍是您只需要从不同的机器广播
- 需要调整 Package.appxmanifest >> Capabilities 设置
- 在 2 台机器(一台 wifi 笔记本电脑和有线台式机)上,我发现检查互联网(客户端)"和互联网(客户端和服务器)"就足够了
- 在带有 2 个 NIC 的第三台台式机上,一个插入一个拔出,它仍然无法使用上述选项,还需要检查私有网络(客户端和服务器)"
- 模拟器似乎创建了自己的子网,您可以通过检查模拟器的网络设置看到这一点,它显然与运行它的台式机不在同一子网上
- 因此,您无法以简单的方式在 Android 模拟器中获得 UDP 广播(除了我没有尝试过的某种转发方案)
- 使用实体 Android 平板电脑(使用 Samsung Galaxy Tab A 8" 测试)验证,它可以工作并且我能够接收 UDP 广播
- 请注意,在 Android 上,我不必像使用 UWP 一样更改默认设置中的任何权限,它可以正常工作
- 到目前为止,尚未在物理 iOS 设备上进行测试,我有一部 iPhone,但我使用的是云 Mac 构建服务器,因此无法在我的设备上进行测试
- 到了处理 iOS 的时候,看来我可能需要买一台本地 Mac
这篇关于无法在 Xamarin.Forms 应用程序中接收 UDP 广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!