unable to receive UDP broadcast in Xamarin.Forms app

独自空忆成欢 提交于 2020-03-21 07:01:49

问题


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.

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.

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.


EDIT: 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.

EDIT: 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.


First, a simple UDP receiver class.

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);
    }
}

Then, the code in App.xaml.cs which uses this class.

    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()
        {
        }
    }


version info

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

回答1:


Got it working for both UWP and Android with help from MS support.

Note that the code provided in the original post is correct and works, given the following considerations.

  • UWP
    • Due to network isolation with UWP, you can't broadcast and receive on the same machine, while this works fine with the console apps, it doesn't work with Xamarin.Forms UWP, so the trick is you just have to broadcast from a different machine
    • Need to adjust Package.appxmanifest >> Capabilities settings
      • On 2 machines (a wifi laptop and wired desktop), I found it was sufficient to have "Internet (Client)" and "Internet (Client & Server)" checked
      • On a 3rd desktop machine with 2 NICs, one plugged in and one unplugged, it still didn't work with the above options, it was necessary to also check the "Private Networks (Client & Server)"
  • Android
    • The emulator appears to create its own subnet, you can see this by checking the emulator's network settings, it clearly isn't on the same subnet as the desktop machine on which its running
    • As a result, you can't get UDP broadcasts in the Android emulator in an easy way (aside from some sort of forwarding scheme which I did not experiment with)
    • Verified that with a physical Android tablet (tested with Samsung Galaxy Tab A 8"), it works and I'm able to receive UDP broadcasts
    • Note that on Android I didn't have to change any permissions from the defaults as with UWP, it worked without issue
  • iOS
    • As of yet, have not tested on a physical iOS device, I have an iPhone, but I'm using a cloud Mac build server so can't test on my device
    • When it comes time to deal with iOS, it looks like I'll probably need to get a local Mac


来源:https://stackoverflow.com/questions/60420560/unable-to-receive-udp-broadcast-in-xamarin-forms-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!