【问题标题】:Dart UDP client/serverDart UDP 客户端/服务器
【发布时间】:2014-01-19 20:14:00
【问题描述】:

我一直在尝试使用 RawDatagramSocket 来实现 udp 客户端,但我有点卡住了。我既不能发送也不能接收任何数据。据我所知,这是 Dart 中的一个非常新的功能,除了 tcp 之外我找不到任何示例。

另外,我不知道是否有错误或什么,但似乎我只能绑定到本地主机。当尝试绑定到另一台计算机 IPV4 地址时,我收到一个套接字异常(由于某些无效的 IP 地址而无法创建数据报套接字)。我已经尝试过 tcp 套接字,将数据连接并发送到用 c# 实现的 tcp 服务器(而 dart 代码在 Mac OS 上运行),没有问题。

有谁做过这方面的工作并且可以提供一个很好的例子吗?

我的代码:

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

编辑

忙了几天,但是在更彻底地阅读了 API 规范之后,在下面的 cmets 的帮助下,我了解到,由于它是一次性侦听器,因此每次发送都必须将 writeEventsEnabled 设置为 true .考虑到 Günter、Fox32 和 Tomas 的 cmets,其余更改非常简单。

我尚未测试将其设置为服务器,但我认为这只是绑定到首选端口的问题(而不是下面示例中的 0)。服务器在 Windows 8.1 上用 C# 实现,而 Dart VM 在 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);
}

【问题讨论】:

  • 不应该绑定只对同一设备的ip地址有效吗?绑定应该设置发件人A​​FAIK的IP地址。这不像连接到另一个 ip,因为 UDP 没有“连接”的概念。
  • 也许这个测试提供了一些信息codereview.chromium.org/85993002/patch/230001/240014
  • 我不知道,Fox32。我已经检查了源代码,获取流实例的唯一方法似乎是通过静态绑定方法。还是我错过了什么?我是飞镖的新手。
  • 您是否尝试绑定到任何地址? => '0.0.0.0'

标签: sockets udp dart dart-io


【解决方案1】:

我不知道这是否是正确的方法,但它对我有用。

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

【讨论】:

    【解决方案2】:

    这应该可以工作

    import 'dart:io';
    import 'dart:convert';
    
    void main() {
      int port = 8082;
    
      // 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");
          }
        });
      });
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-22
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多