Dart SocketControlMessage
last modified April 4, 2025
The SocketControlMessage
class in Dart represents network control
messages used with sockets. These messages carry protocol-specific information.
Control messages are typically used for advanced socket operations like
accessing packet headers or setting socket options. They're part of Dart's
dart:io
library for low-level network programming.
Basic Definition
SocketControlMessage
is an abstract class representing platform-
specific control messages. It's used with RawDatagramSocket and RawSocket.
Key features include protocol-specific data access and platform independence. The actual implementation varies by operating system and protocol.
Basic SocketControlMessage Usage
This example shows how to receive control messages from a datagram socket.
import 'dart:io'; import 'dart:typed_data'; void main() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); final controlMessages = socket.receiveControlMessages(); if (controlMessages != null) { for (final message in controlMessages) { print('Received control message: ${message.runtimeType}'); } } } }); // Send a test packet to ourselves socket.send(Uint8List.fromList([1, 2, 3]), InternetAddress.loopbackIPv4, socket.port); }
We create a datagram socket and listen for incoming packets with control messages. The receiveControlMessages() method returns any control messages.
$ dart main.dart Received control message: _RawSocketControlMessage
Working with IP_TTL Control Messages
This example demonstrates handling IP time-to-live (TTL) control messages.
import 'dart:io'; import 'dart:typed_data'; void main() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); // Enable receiving TTL information socket.setOption(SocketOption.ipReceiveTTL, true); socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); final controlMessages = socket.receiveControlMessages(); if (controlMessages != null) { for (final message in controlMessages) { if (message.level == SocketOption.ipLevel && message.type == SocketOption.ipTTL) { print('Packet TTL: ${message.data[0]}'); } } } } }); // Send test packet socket.send(Uint8List.fromList([1, 2, 3]), InternetAddress.loopbackIPv4, socket.port); }
We configure the socket to receive TTL information and then extract it from control messages. The message contains protocol level and type information.
$ dart main.dart Packet TTL: 64
Sending Control Messages
This example shows how to send packets with control messages attached.
import 'dart:io'; import 'dart:typed_data'; void main() async { final receiver = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); final sender = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); // Enable TTL control messages on receiver receiver.setOption(SocketOption.ipReceiveTTL, true); receiver.listen((event) { if (event == RawSocketEvent.read) { final datagram = receiver.receive(); final controlMessages = receiver.receiveControlMessages(); if (controlMessages != null) { for (final message in controlMessages) { print('Received TTL: ${message.data[0]}'); } } } }); // Create control message to set TTL final ttlMessage = RawSocketControlMessage.fromHandled( SocketOption.ipLevel, SocketOption.ipTTL, Uint8List.fromList([1]) // Set TTL to 1 ); // Send with control message sender.send( Uint8List.fromList([1, 2, 3]), InternetAddress.loopbackIPv4, receiver.port, controlMessages: [ttlMessage] ); }
We create a control message to set the TTL value and attach it to an outgoing packet. The receiver will see this TTL value in its control messages.
$ dart main.dart Received TTL: 1
Handling Multiple Control Messages
This example demonstrates processing different types of control messages.
import 'dart:io'; import 'dart:typed_data'; void main() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); // Enable multiple control message types socket.setOption(SocketOption.ipReceiveTTL, true); socket.setOption(SocketOption.ipReceiveTOS, true); socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); final controlMessages = socket.receiveControlMessages(); if (controlMessages != null) { for (final message in controlMessages) { if (message.level == SocketOption.ipLevel) { if (message.type == SocketOption.ipTTL) { print('TTL: ${message.data[0]}'); } else if (message.type == SocketOption.ipTOS) { print('TOS: ${message.data[0]}'); } } } } } }); // Send test packet socket.send(Uint8List.fromList([1, 2, 3]), InternetAddress.loopbackIPv4, socket.port); }
We configure the socket to receive both TTL and TOS (Type of Service) control messages. The code distinguishes between different message types.
$ dart main.dart TTL: 64 TOS: 0
Platform-Specific Control Messages
This example shows platform-specific handling of control messages.
import 'dart:io'; import 'dart:typed_data'; void main() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0); // Platform-specific options if (Platform.isLinux) { socket.setOption(SocketOption.ipPacketInfo, true); } else if (Platform.isMacOS) { socket.setOption(SocketOption.ipRecvDstAddr, true); } socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); final controlMessages = socket.receiveControlMessages(); if (controlMessages != null) { print('Received ${controlMessages.length} control messages'); for (final message in controlMessages) { print('Message level: ${message.level}, type: ${message.type}'); print('Data length: ${message.data.length} bytes'); } } } }); // Send test packet socket.send(Uint8List.fromList([1, 2, 3]), InternetAddress.loopbackIPv4, socket.port); }
We demonstrate platform-specific control message options. The actual available options and message formats vary by operating system.
$ dart main.dart Received 1 control messages Message level: 0, type: 8 Data length: 12 bytes
Best Practices
- Check platform: Control message options vary by OS
- Enable explicitly: Set required socket options first
- Handle null: receiveControlMessages() may return null
- Validate: Check message level and type before processing
- Performance: Control messages add overhead, use judiciously
Source
Dart SocketControlMessage Documentation
This tutorial covered Dart's SocketControlMessage class with practical examples showing reception, sending, and platform-specific handling of control messages.
Author
List all Dart tutorials.