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;
}