Home > Blockchain >  Xamarin MulticastLock Acquiring doesn't allow multicast
Xamarin MulticastLock Acquiring doesn't allow multicast

Time:04-28

I am using Xamarin to create an Android application. This app must, among other things, receive a multicast stream. The server is sending fine, but my app is not receiving properly. If I acquire the multicast lock, which is what my research seems say is all I need to do, I can see I have the lock, but the app still does not receive the data.

var wifiManager = var wifiManager = (WifiManager)Application.Context.GetSystemService(Context.WifiService);
// Acquire the lock
if (wifiManager != null)
{
    // _lock is a private member WifiManager.MulticastLock _lock
    _lock = wifiManager.CreateMulticastLock("PiEar");

    if (_lock != null)
    {
        _lock.Acquire();
    } 
    else
    {
        Debug.WriteLine("Could not acquire multicast lock"); // Does not print, meaning I do acquire the lock (and _lock.IsHeld() returns true)
    }
} 
else 
{
    Debug.WriteLine("WifiManager is null"); // Does not print, meaning it is not null
}

If I then use a different app, MSniffer, it not only receives the data, but allows my app to do so as well. Am I doing something wrong with attempting to acquire the lock?

Also, I have the following permissions:

  • ACCESS_WIFI_STATE
  • CHANGE_WIFI_STATE
  • ACCESS_NETWORK_STATE
  • INTERNET
  • CHANGE_WIFI_MULTICAST_STATE

Edit 1: More info

The .cs page's code in question is below. _receivedMessages is a ListView, allowing me to visually see received data. The above code is what is run on line 2 below. The only code in the dependency service is the code acquiring the lock.

var service = DependencyService.Get<IMulticastLock>();
service.Acquire();
Task.Run(async () =>
{
    while (true)
    {
        try
        {
            var endpoint = new IPEndPoint(IPAddress.Parse("224.0.0.69"), 6666);
            var multicast = new UdpClient(endpoint);
            while (true)
            {

                var multicastBytes = await multicast.ReceiveAsync();
                var message = Encoding.UTF8.GetString(multicastBytes.Buffer);
                Debug.WriteLine($"Received: {message}");
                Device.BeginInvokeOnMainThread(() =>
                {
                    _receivedMessages.Add(message);
                });
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
        }
    }
});

CodePudding user response:

  1. Check the IPAddress and ports.

  2. You could try to use the code below about how to create and configure UdpClient.

    public class MulticastUdpClient
    {
     UdpClient _udpclient;
     int _port;
     IPAddress _multicastIPaddress;
     IPAddress _localIPaddress;
     IPEndPoint _localEndPoint;
     IPEndPoint _remoteEndPoint;
    
     public MulticastUdpClient(IPAddress multicastIPaddress, int port, IPAddress localIPaddress = null)
     {
         // Store params
         _multicastIPaddress = multicastIPaddress;
         _port = port;
         _localIPaddress = localIPaddress;
         if (localIPaddress == null)
             _localIPaddress = IPAddress.Any;
    
         // Create endpoints
         _remoteEndPoint = new IPEndPoint(_multicastIPaddress, port);
         _localEndPoint = new IPEndPoint(_localIPaddress, port);
    
         // Create and configure UdpClient
         _udpclient = new UdpClient();
         // The following three lines allow multiple clients on the same PC
         _udpclient.ExclusiveAddressUse = false;
         _udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
         _udpclient.ExclusiveAddressUse = false;
         // Bind, Join
         _udpclient.Client.Bind(_localEndPoint);
         _udpclient.JoinMulticastGroup(_multicastIPaddress, _localIPaddress);
    
         // Start listening for incoming data
         _udpclient.BeginReceive(new AsyncCallback(ReceivedCallback), null);
     }
    
     /// <summary>
     /// Send the buffer by UDP to multicast address
     /// </summary>
     /// <param name="bufferToSend"></param>
     public void SendMulticast(byte[] bufferToSend)
     {
         _udpclient.Send(bufferToSend, bufferToSend.Length, _remoteEndPoint);
     }
    
     /// <summary>
     /// Callback which is called when UDP packet is received
     /// </summary>
     /// <param name="ar"></param>
     private void ReceivedCallback(IAsyncResult ar)
     {
         // Get received data
         IPEndPoint sender = new IPEndPoint(0, 0);
         Byte[] receivedBytes = _udpclient.EndReceive(ar, ref sender);
    
         // fire event if defined
         if (UdpMessageReceived != null)
             UdpMessageReceived(this, new UdpMessageReceivedEventArgs() { Buffer = receivedBytes });
    
         // Restart listening for udp data packages
         _udpclient.BeginReceive(new AsyncCallback(ReceivedCallback), null);
     }
    
     /// <summary>
     /// Event handler which will be invoked when UDP message is received
     /// </summary>
     public event EventHandler<UdpMessageReceivedEventArgs> UdpMessageReceived;
    
     /// <summary>
     /// Arguments for UdpMessageReceived event handler
     /// </summary>
     public class UdpMessageReceivedEventArgs: EventArgs
     {
         public byte[] Buffer {get;set;}
     }
    
    }
    
  • Related