Dart SocketControlMessage
最后修改于 2025 年 4 月 4 日
Dart 中的 SocketControlMessage 类代表与套接字一起使用的网络控制消息。这些消息携带协议特定的信息。
控制消息通常用于高级套接字操作,例如访问数据包头部或设置套接字选项。它们是 Dart dart:io 库的一部分,用于低级网络编程。
基本定义
SocketControlMessage 是一个抽象类,代表特定于平台的控制消息。它与 RawDatagramSocket 和 RawSocket 一起使用。
主要功能包括协议特定的数据访问和平台独立性。实际实现因操作系统和协议而异。
基本的 SocketControlMessage 用法
此示例演示如何从数据报套接字接收控制消息。
main.dart
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);
}
我们创建一个数据报套接字并监听带有控制消息的传入数据包。receiveControlMessages() 方法返回任何控制消息。
$ dart main.dart Received control message: _RawSocketControlMessage
处理 IP_TTL 控制消息
此示例演示了处理 IP 生存时间 (TTL) 控制消息。
main.dart
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);
}
我们配置套接字以接收 TTL 信息,然后从控制消息中提取它。消息包含协议级别和类型信息。
$ dart main.dart Packet TTL: 64
发送控制消息
此示例展示了如何发送附加了控制消息的数据包。
main.dart
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]
);
}
我们创建一个控制消息来设置 TTL 值,并将其附加到传出的数据包。接收者将在其控制消息中看到此 TTL 值。
$ dart main.dart Received TTL: 1
处理多个控制消息
此示例演示了处理不同类型的控制消息。
main.dart
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);
}
我们配置套接字以接收 TTL 和 TOS(服务类型)控制消息。代码区分了不同的消息类型。
$ dart main.dart TTL: 64 TOS: 0
特定于平台的控制消息
此示例展示了特定于平台的控制消息处理。
main.dart
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);
}
我们演示了特定于平台的控制消息选项。实际可用的选项和消息格式因操作系统而异。
$ dart main.dart Received 1 control messages Message level: 0, type: 8 Data length: 12 bytes
最佳实践
- 检查平台:控制消息选项因操作系统而异
- 显式启用:首先设置所需的套接字选项
- 处理 null:receiveControlMessages() 可能返回 null
- 验证:在处理之前检查消息级别和类型
- 性能:控制消息会增加开销,请谨慎使用
来源
本教程通过实际示例介绍了 Dart 的 SocketControlMessage 类,展示了控制消息的接收、发送和特定于平台的处理。
作者
列出 所有 Dart 教程。