sdk
sdk copied to clipboard
Not able to close/release RawDatagramSocket after receiving a SocketException in Windows Desktop
Scanning a local network using UDP packets and the RawDatagramSocket, the socket resources are never released when the socket is seeing a SocketException.
Reproduced using a slightly modified example from the official docs: https://api.dart.dev/stable/3.5.0/dart-io/RawDatagramSocket-class.html
import 'dart:io';
import 'dart:typed_data';
void main() async {
// Read the current time from an NTP server.
final serverAddress = InternetAddress("192.168.130.92");
final clientSocket = await RawDatagramSocket.bind(
serverAddress.type == InternetAddressType.IPv6
? InternetAddress.anyIPv6
: InternetAddress.anyIPv4,
0);
final ntpQuery = Uint8List(48);
ntpQuery[0] = 0x23; // See RFC 5905 7.3
clientSocket.listen((event) {
switch (event) {
case RawSocketEvent.read:
final datagram = clientSocket.receive();
// Parse `datagram.data`
clientSocket.close();
break;
case RawSocketEvent.write:
if (clientSocket.send(ntpQuery, serverAddress, 123) > 0) {
clientSocket.writeEventsEnabled = false;
}
break;
case RawSocketEvent.closed:
break;
default:
throw "Unexpected event $event";
}
}).onError((e) {
print(e);
});
Future.delayed(Duration(seconds: 1)).then((_) {
print('Closing socket');
clientSocket.close();
});
}
At the specific server address I have a pixl8 device, but it may be any device and when I send a UDP to that address I'm seeing a SocketException from the RawDatagramSocket listener. Using wireshark I see an ICMP response with port unreachable:
The effect in the example code is that we print the exception to the console. Then I try to close the socket on a timer, but the session never exits:
$ dart --version Dart SDK version: 3.5.0 (stable) (Tue Jul 30 02:17:59 2024 -0700) on "windows_x64"
Summary: The RawDatagramSocket on Windows Desktop fails to close and release resources after receiving a SocketException, specifically a "Port Unreachable" ICMP response. This occurs when sending UDP packets to an unreachable address, causing the socket to remain open indefinitely.
cc @brianquinlan