Home > Software design >  Dart UDP socket won't timeout
Dart UDP socket won't timeout

Time:11-02

I want to create a UDP socket that broadcasts some data, then listens for responses from an arbitrary number of devices for 5 seconds (some code to support multiple responses has been removed for simplicity). The code below broadcasts as expected and receives responses as expected, but it never times out and appears to be listening forever. I would think that the timeout function would simply set the timeout of the socket, but instead it seems to do nothing except return an instance of Stream<RawSocketEvent> which seems unhelpful unless I'm missing something.

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

Future <void> sendData() async {
  List<int> buffer = utf8.encode('foobar');
  RawDatagramSocket s = await RawDatagramSocket.bind(InternetAddress('192.168.1.123'), 0);  // My PC's IP
  s.broadcastEnabled = true;

  // A call to `timeout` returns an instance of `Stream<RawSocketEvent>`, so I
  // don't expect this to do anything the way I have it implemented, but a
  // timeout of 5 seconds on the listen is what I'm trying to accomplish.
  s.timeout(Duration(seconds: 5));
  var subscription = s.listen((RawSocketEvent e) async {
    Datagram? dg = s.receive();
    if (dg != null) {
      print('Received:');
      print(utf8.decode(dg.data));
    }
  });

  s.send(buffer, InternetAddress('255.255.255.255'), 1234);
  await subscription.asFuture<void>(); // Never gets past here
  s.close();
}


Future<void> main() async {
  await sendData();
  exit(0);
}

I've tried several variations on this code, but I always get one of two results; listen never times out, or main returns before any data is received on the socket (but send was successful).

CodePudding user response:

Still unclear why the timeout function doesn't set the timeout as one would expect, or why await subscription.asFuture<void>() from my OP didn't work, but the changes below do seem to work:

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

Future <void> sendData() async {
  List<int> buffer = utf8.encode('foobar');
  RawDatagramSocket s = await RawDatagramSocket.bind(InternetAddress('192.168.1.123'), 0);  // My PC's IP
  s.broadcastEnabled = true;

  s.listen((RawSocketEvent e) {
    Datagram? dg = s.receive();
    if (dg != null) {
      print('Received:');
      print(utf8.decode(dg.data));
    }
  });

  s.send(buffer, InternetAddress('255.255.255.255'), 1234);
  
  await Future.delayed(Duration(seconds: 5)).then((value) {
    s.close();
  });
}


main() async {
  await sendData();
  exit(0);
}
  • Related