Обмен UDP-сообщениями в Dart
Полный цикл в одной программе: сокет приемника
слушает порт, читает запрос и шлет ответ. Сокет
отправителя передает датаграмму и ждет ответ
через тот же RawDatagramSocket.
Номер порта приемника берут из port после
bind с нулем. Ответ отправитель печатает
строкой из байтов:
import 'dart:async';
import 'dart:convert';
import 'dart:io';
void main() async {
var receiver = await RawDatagramSocket.bind(
InternetAddress.loopbackIPv4,
0,
);
var listenPort = receiver.port;
var requestDone = Completer<void>();
receiver.listen((event) {
if (event == RawSocketEvent.read) {
var datagram = receiver.receive();
if (datagram != null) {
receiver.send(
utf8.encode('pong'),
datagram.address,
datagram.port,
);
requestDone.complete();
}
}
});
var sender = await RawDatagramSocket.bind(
InternetAddress.loopbackIPv4,
0,
);
var answerDone = Completer<void>();
sender.listen((event) {
if (event == RawSocketEvent.read) {
var datagram = sender.receive();
if (datagram != null) {
print(utf8.decode(datagram.data));
answerDone.complete();
}
}
});
sender.send(
utf8.encode('ping'),
InternetAddress.loopbackIPv4,
listenPort,
);
await requestDone.future;
await answerDone.future;
receiver.close();
sender.close();
}
Тот же каркас подходит для других коротких фраз.
Главное - не закрывать сокет отправителя до
приема ответа и держать подписку listen,
пока идет обмен:
import 'dart:async';
import 'dart:convert';
import 'dart:io';
void main() async {
var receiver = await RawDatagramSocket.bind(
InternetAddress.loopbackIPv4,
0,
);
var listenPort = receiver.port;
var requestDone = Completer<void>();
receiver.listen((event) {
if (event == RawSocketEvent.read) {
var datagram = receiver.receive();
if (datagram != null) {
receiver.send(
utf8.encode('done'),
datagram.address,
datagram.port,
);
requestDone.complete();
}
}
});
var sender = await RawDatagramSocket.bind(
InternetAddress.loopbackIPv4,
0,
);
var answerDone = Completer<void>();
sender.listen((event) {
if (event == RawSocketEvent.read) {
var datagram = sender.receive();
if (datagram != null) {
print(utf8.decode(datagram.data));
answerDone.complete();
}
}
});
sender.send(
utf8.encode('start job'),
InternetAddress.loopbackIPv4,
listenPort,
);
await requestDone.future;
await answerDone.future;
receiver.close();
sender.close();
}
Отправьте "time" и выведите ответ
"now" в консоли отправителя.
Обменяйтесь фразами "ask" и
"reply" в одном запуске. На экране
должна появиться только строка ответа.