Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've been trying to implement a udp client by using the RawDatagramSocket but I'm kind of stuck. I can neither send or receive any data. It's a pretty new feature in Dart as far as I know and I can't find any examples except for tcp.

Also, I don't know if there is a bug or anything, but it seems like I can only bind to the localhost. When trying to bind to another computer IPV4 address, I receive a socket exception (failure to create datagram socket due to some invalid IP address). I've tried the tcp socket, connecting and sending data to a tcp server implemented in c# (while the dart code was running on Mac OS), without a problem.

Anyone who has worked on it and can provide a nice example?

My code:

import 'dart:io';
import 'dart:convert';
void main() {
  var data = "Hello, World";
  var codec = new Utf8Codec();
  List<int> dataToSend = codec.encode(data);
  //var address = new InternetAddress('172.16.32.73');
  var address = new InternetAddress('127.0.0.1');
  RawDatagramSocket.bind(address, 16123).then((udpSocket) {
    udpSocket.listen((e) {
      print(e.toString());
      Datagram dg = udpSocket.receive();
      if(dg != null) 
        dg.data.forEach((x) => print(x));
    udpSocket.send(dataToSend, new InternetAddress('172.16.32.73'), 16123);
    print('Did send data on the stream..');

Been busy for a couple of days but after reading the API spec more thoroughly, and with some help from the comments below, I learned that, since it's a one-shot listener, the writeEventsEnabled must be set to true for every send. The rest of the changes are pretty straightforward given the comments by Günter, Fox32 and Tomas.

I haven't tested to set it up as a server yet but I assume that's just a matter of binding to the preferred port (instead of 0 as in the example below). The server was implemented in C# on a Windows 8.1, while the Dart VM was running on Mac OS X.

import 'dart:async';
import 'dart:io';
import 'dart:convert';
void connect(InternetAddress clientAddress, int port) {
  Future.wait([RawDatagramSocket.bind(InternetAddress.ANY_IP_V4, 0)]).then((values) {
    RawDatagramSocket udpSocket = values[0];
    udpSocket.listen((RawSocketEvent e) {
      print(e);
      switch(e) {
        case RawSocketEvent.READ :
          Datagram dg = udpSocket.receive();
          if(dg != null) {
            dg.data.forEach((x) => print(x));
          udpSocket.writeEventsEnabled = true;
          break;
        case RawSocketEvent.WRITE : 
          udpSocket.send(new Utf8Codec().encode('Hello from client'), clientAddress, port);
          break;
        case RawSocketEvent.CLOSED : 
          print('Client disconnected.');
void main() {
  print("Connecting to server..");
  var address = new InternetAddress('172.16.32.71');
  int port = 16123;
  connect(address, port);
                Shouldn't bind only work for ip addresses of the same device? Bind should set the the ip address of the sender AFAIK. It isn't something like connecting to another ip, as UDP doesn't have a concept of a "connection".
– Fox32
                Jan 19, 2014 at 20:34
                maybe this tests provide some information codereview.chromium.org/85993002/patch/230001/240014
– Günter Zöchbauer
                Jan 19, 2014 at 20:36
                I don't know, Fox32. I've checked around in the source and the only way of getting the stream instance seems to be via the static bind method. Or have I missed anything? I'm a bit of a newbie on dart.
– Joachim Birche
                Jan 19, 2014 at 20:39

I don't know if this is the right way to do it, but it got it working for me.

import 'dart:io';
import 'dart:convert';
void main() {
  var data = "Hello, World";
  var codec = new Utf8Codec();
  List<int> dataToSend = codec.encode(data);
  var addressesIListenFrom = InternetAddress.anyIPv4;
  int portIListenOn = 16123; //0 is random
  RawDatagramSocket.bind(addressesIListenFrom, portIListenOn)
    .then((RawDatagramSocket udpSocket) {
    udpSocket.forEach((RawSocketEvent event) {
      if(event == RawSocketEvent.read) {
        Datagram dg = udpSocket.receive();
        dg.data.forEach((x) => print(x));
    udpSocket.send(dataToSend, addressesIListenFrom, portIListenOn);
    print('Did send data on the stream..');
  // listen forever & send response
  RawDatagramSocket.bind(InternetAddress.anyIPv4, port).then((socket) {
    socket.listen((RawSocketEvent event) {
      if (event == RawSocketEvent.read) {
        Datagram dg = socket.receive();
        if (dg == null) return;
        final recvd = String.fromCharCodes(dg.data);
        /// send ack to anyone who sends ping
        if (recvd == "ping") socket.send(Utf8Codec().encode("ping ack"), dg.address, port);
        print("$recvd from ${dg.address.address}:${dg.port}");
  print("udp listening on $port");
  // send single packet then close the socket
  RawDatagramSocket.bind(InternetAddress.anyIPv4, port).then((socket) {
    socket.send(Utf8Codec().encode("single send"), InternetAddress("192.168.1.19"), port);
    socket.listen((event) {
      if (event == RawSocketEvent.write) {
        socket.close();
        print("single closed");
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.