Dart UDP客户端/服务器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dart UDP客户端/服务器相关的知识,希望对你有一定的参考价值。

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

此外,我不知道是否有错误或任何东西,但似乎我只能绑定到localhost。当尝试绑定到另一台计算机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规范之后,在下面的评论中得到了一些帮助,我了解到,由于它是一次性监听器,因此每次发送都必须将writeEventsEnabled设置为true。鉴于Günter,Fox32和Tomas的评论,其余的变化非常简单。

我还没有测试过将它设置为服务器但是我认为这只是绑定到首选端口的问题(而不是如下例中的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);
}
答案

我不知道这是否是正确的方法,但它让它适合我。

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, new InternetAddress('172.16.32.73'), 16123);
    print('Did send data on the stream..');
  });
}

以上是关于Dart UDP客户端/服务器的主要内容,如果未能解决你的问题,请参考以下文章

基于UDP的客户端和服务器端的代码设计

UDP服务器客户端编程流程

Udp打洞原理和源代码。

udp简单客户端和服务端的通信代码

Erlang Udp 服务器丢弃大量数据包

Udp客户端与服务通讯