Dart - Send an UDP broadcast
Asked Answered
F

2

10

I'm asking for help since it seems I cannot find a way to send an UDP broadcast inside a local network using Dart.

So far I managed to communicate using UDP with RawDatagramSocket. I'm able to send a message to a specific address.

What I'm not able to do is to send a broadcast to any device inside a local network (network mask is 255.255.255.0), and to wait for possible (multiple) answer(s). Here is the code I'm using:

RawDatagramSocket.bind('127.0.0.1', 8889)
    .then((RawDatagramSocket udpSocket) {
        udpSocket.listen((e) {
            Datagram dg = udpSocket.receive();
            if (dg != null) {
                //stuff
            }
        });
        udpSocket.send(utf8.encode('TEST'), DESTINATION_ADDRESS, 8889);
});

I tried to replace DESTINATION_ADDRESS with InternetAddress.anyIPv4, but I had no luck. I also found the property broadcastEnabled inside RawDatagramSocket, but I cannot find further informations about how to make use of it.

Thanks in advance for you help.

Fancy answered 23/1, 2019 at 13:3 Comment(1)
Broadcast UDP is often blocked by network devices due to the load it causes. Consider using multicast to get a message out to multiple receivers.Rad
F
12

There are two problems:

  1. Use InternetAddress.anyIPv4 for binding on all network interfaces;

  2. Enable permission for broadcasting with property broadcastEnabled

Obviously use a broadcast address: for a /24 network use x.y.z.255 address.

This snippet works:

import 'dart:io';
import 'dart:convert';

main() {

  var DESTINATION_ADDRESS=InternetAddress("x.y.z.255");

  RawDatagramSocket.bind(InternetAddress.anyIPv4, 8889).then((RawDatagramSocket udpSocket) {
    udpSocket.broadcastEnabled = true;
    udpSocket.listen((e) {
      Datagram dg = udpSocket.receive();
      if (dg != null) {
        print("received ${dg.data}");
      }
    });
    List<int> data =utf8.encode('TEST');
    udpSocket.send(data, DESTINATION_ADDRESS, 8889);
  });
}
Fakieh answered 23/1, 2019 at 15:4 Comment(10)
Unfortunately, this has been my first approach (and I just tested it again using your snippet), but it doesn't work. Let's say I have a sever listening for UDP packets at 'x.y.z.5': if DESTINATION_ADDRESS is set to 'x.y.z.255' the server doesn't receive anything, but if it's set to 'x.y.z.5' the server correctly receives the packet.Fancy
For me it works using the same host. It should be a receiver side problem. Are you binding to the broadcast address x.y.x.255?Fakieh
Thanks, I managed to make it work, though it didn't actually solve my problem. Thing is, I'm using Flutter, and I thought that mentioning Dart or Flutter would have been equivalent. It turned out it isn't. In a simple .dart script the broadcast works, and I'm able to receive the message even from another host. Using Flutter, the same script isn't working. Are you able to help me, or should I seek help asking a new question?Fancy
It sound like you are you using an emulator. Try a real device, It should work.Fakieh
I'm having the same issue with Flutter. Have you solved this one @Fancy ?Galvan
@GabrielZiegler Yes, as suggested by attdona I used a real device and it worked. Probably with some tweaks you can make it work on an emulator, but I haven't tried it.Fancy
I was already using a real device, but it wouldn't work. I have managed to use Adhara Socket for this tho.Galvan
how should I enable permission for broadcastEnabledFascista
Thanks so much @attdona, this solved my issue. I was able to send my udp packet and now with the socket bound to InternetAddress.anyIPv4 it was able to get the response from the server I was looking for. The permissions thing was also a very helpful fix.Viridi
If you are testing your flutter app on an emulator you should be aware that you will not be on the same LAN as your development computer. Sometimes it is just easier to debug with a physical device.Laboy
E
0
socket.send(
  'HELLO!'.codeUnits,
  InternetAddress('255.255.255.255'),
  8080,
);

Try LAN instead of WLAN.

Ewer answered 12/3, 2019 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.