admin管理员组

文章数量:1026657

My example code below is working in Android, but in Windows it never be able to receive any message. Can anyone give me hint about what is the problem? Thanks.

Note: it is complete code in main.dart, you can copy it to your main.dart and run it. Note: originally it can't be posted to SO because of this message: "It looks like your post is mostly code; please add some more details.". So I add some more text, please ignore this second note.

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:async';
import 'dart:math';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    Timer(Duration(milliseconds: 0), () async {
      InternetAddress mine = await getMyIPAddress();
      startUdpReceiver(mine);
    });
  }
  
  String myIp = "";
  int myPort = 0;
  String dataReceived = "";
  startUdpReceiver(InternetAddress mine) {
    RawDatagramSocket.bind(mine.address, 0).then((RawDatagramSocket socket) {
      myIp = "${mine.address}";
      myPort = socket.port;
      setState(() { });
      socket.listen((RawSocketEvent e) {
        Datagram? d = socket.receive();
        if (d != null) {
          dataReceived = new String.fromCharCodes(d.data).trim();
          setState(() { });
          dynamic detail = {};
          try { detail = jsonDecode(dataReceived); } catch (e) {}
          if (detail["senderIp"] != null && detail["message"] == "testing") {
            sendData(detail["senderIp"], detail["senderPort"], "Message received: "+detail["message"]);
          }
        }
      });
    });
  }
  String dataSent = "";
  void sendData(String toIp, int toPort, String message) {
    RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).then((RawDatagramSocket socket){
      String data = jsonEncode({"senderIp":myIp,"senderPort":myPort,"message":message});
      dataSent = "to $toIp:$toPort: "+data;
      setState(() { });
      socket.send(utf8.encode(data), InternetAddress(toIp), toPort);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("My address: $myIp:$myPort"),
            Text("Data sent: $dataSent"),
            Text("Data received: $dataReceived"),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          String txt = await gettext(context, "IP:Port");
          if (txt != "") {
            String toIp = txt.split(":").first;
            String toPort = txt.split(":").last;
            sendData(toIp, int.parse(toPort), "testing");
          }
        },
        tooltip: 'Send',
        child: const Icon(Icons.send),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Future<InternetAddress> getMyIPAddress() async {
  //not mine, copied from SO
  InternetAddress result;

  int code = Random().nextInt(255);
  var dgSocket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
  dgSocket.readEventsEnabled = true;
  dgSocket.broadcastEnabled = true;
  Future<InternetAddress> ret =
      dgSocket.timeout(Duration(milliseconds: 100), onTimeout: (sink) {
    sink.close();
  }).expand<InternetAddress>((event) {
    if (event == RawSocketEvent.read) {
      Datagram? dg = dgSocket.receive();
      if (dg != null && dg.data.length == 1 && dg.data[0] == code) {
        dgSocket.close();
        return [dg.address];
      }
    }
    return [];
  }).firstWhere((InternetAddress a) => a != null);

  dgSocket.send([code], InternetAddress("255.255.255.255"), dgSocket.port);
  return ret;
}  

Future<String> gettext(BuildContext context, String message) async {
  //not mine, copied from SO
  String tex = '';
  bool ok = false;
  await showDialog(
    context: context,
    builder: (context) {
      return AlertDialog(
        content: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(message),
            TextField(
                onChanged: (value) {
                  tex = value;
                }),
          ],
        ),
        actions: [
          ElevatedButton(
            child: Text("OK"),
            onPressed: () {
              ok = true;
              Navigator.pop(context);
            }
          ),
          ElevatedButton(
            child: Text("Cancel"),
            onPressed: () {
              Navigator.pop(context);
            }
          ),
        ],
      );
    },
  );
  return tex;
}

My example code below is working in Android, but in Windows it never be able to receive any message. Can anyone give me hint about what is the problem? Thanks.

Note: it is complete code in main.dart, you can copy it to your main.dart and run it. Note: originally it can't be posted to SO because of this message: "It looks like your post is mostly code; please add some more details.". So I add some more text, please ignore this second note.

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:async';
import 'dart:math';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    Timer(Duration(milliseconds: 0), () async {
      InternetAddress mine = await getMyIPAddress();
      startUdpReceiver(mine);
    });
  }
  
  String myIp = "";
  int myPort = 0;
  String dataReceived = "";
  startUdpReceiver(InternetAddress mine) {
    RawDatagramSocket.bind(mine.address, 0).then((RawDatagramSocket socket) {
      myIp = "${mine.address}";
      myPort = socket.port;
      setState(() { });
      socket.listen((RawSocketEvent e) {
        Datagram? d = socket.receive();
        if (d != null) {
          dataReceived = new String.fromCharCodes(d.data).trim();
          setState(() { });
          dynamic detail = {};
          try { detail = jsonDecode(dataReceived); } catch (e) {}
          if (detail["senderIp"] != null && detail["message"] == "testing") {
            sendData(detail["senderIp"], detail["senderPort"], "Message received: "+detail["message"]);
          }
        }
      });
    });
  }
  String dataSent = "";
  void sendData(String toIp, int toPort, String message) {
    RawDatagramSocket.bind(InternetAddress.anyIPv4, 0).then((RawDatagramSocket socket){
      String data = jsonEncode({"senderIp":myIp,"senderPort":myPort,"message":message});
      dataSent = "to $toIp:$toPort: "+data;
      setState(() { });
      socket.send(utf8.encode(data), InternetAddress(toIp), toPort);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("My address: $myIp:$myPort"),
            Text("Data sent: $dataSent"),
            Text("Data received: $dataReceived"),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          String txt = await gettext(context, "IP:Port");
          if (txt != "") {
            String toIp = txt.split(":").first;
            String toPort = txt.split(":").last;
            sendData(toIp, int.parse(toPort), "testing");
          }
        },
        tooltip: 'Send',
        child: const Icon(Icons.send),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Future<InternetAddress> getMyIPAddress() async {
  //not mine, copied from SO
  InternetAddress result;

  int code = Random().nextInt(255);
  var dgSocket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
  dgSocket.readEventsEnabled = true;
  dgSocket.broadcastEnabled = true;
  Future<InternetAddress> ret =
      dgSocket.timeout(Duration(milliseconds: 100), onTimeout: (sink) {
    sink.close();
  }).expand<InternetAddress>((event) {
    if (event == RawSocketEvent.read) {
      Datagram? dg = dgSocket.receive();
      if (dg != null && dg.data.length == 1 && dg.data[0] == code) {
        dgSocket.close();
        return [dg.address];
      }
    }
    return [];
  }).firstWhere((InternetAddress a) => a != null);

  dgSocket.send([code], InternetAddress("255.255.255.255"), dgSocket.port);
  return ret;
}  

Future<String> gettext(BuildContext context, String message) async {
  //not mine, copied from SO
  String tex = '';
  bool ok = false;
  await showDialog(
    context: context,
    builder: (context) {
      return AlertDialog(
        content: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(message),
            TextField(
                onChanged: (value) {
                  tex = value;
                }),
          ],
        ),
        actions: [
          ElevatedButton(
            child: Text("OK"),
            onPressed: () {
              ok = true;
              Navigator.pop(context);
            }
          ),
          ElevatedButton(
            child: Text("Cancel"),
            onPressed: () {
              Navigator.pop(context);
            }
          ),
        ],
      );
    },
  );
  return tex;
}

本文标签: flutterUDP on Windows never receive messageStack Overflow