Dart RawSocketEvent
最后修改于 2025 年 4 月 4 日
Dart 中的 RawSocketEvent 类代表原始套接字连接上发生的事件。它与 RawSocket 一起用于低级网络通信。
RawSocketEvent 提供了读取、写入、关闭和错误状态的事件类型。它是 Dart dart:io 库的一部分,用于非 Web 应用程序。
基本定义
RawSocketEvent 是一个枚举类,用于定义套接字事件。这些事件在套接字操作期间触发,并且必须进行处理。
关键事件包括 READ(用于传入数据)、WRITE(用于输出就绪)和 CLOSED(用于连接终止)。错误情况也会被报告。
基本的 Socket 事件处理
此示例展示了使用 RawSocketEvent 进行基本的事件处理。
main.dart
import 'dart:io';
void main() async {
var socket = await RawSocket.connect('example.com', 80);
socket.listen((event) {
switch (event) {
case RawSocketEvent.read:
print('Data available to read');
break;
case RawSocketEvent.write:
print('Ready to send data');
break;
case RawSocketEvent.closed:
print('Connection closed');
break;
}
});
socket.writeEventsEnabled = true;
}
我们连接到服务器并监听套接字事件。listen 回调接收 RawSocketEvent 值,指示套接字状态的变化。
$ dart main.dart Ready to send data Data available to read Connection closed
在 READ 事件上读取数据
此示例演示了在发生 READ 事件时读取数据。
main.dart
import 'dart:io';
import 'dart:convert';
void main() async {
var socket = await RawSocket.connect('example.com', 80);
var request = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n';
socket.write(request.codeUnits);
socket.listen((event) {
if (event == RawSocketEvent.read) {
var data = socket.read();
if (data != null) {
print(utf8.decode(data));
}
} else if (event == RawSocketEvent.closed) {
socket.close();
}
});
}
我们发送一个 HTTP 请求,并在发生 READ 事件时读取响应。socket.read() 方法将可用数据作为字节列表返回。
$ dart main.dart HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 ...
处理 Write 事件
此示例展示了如何处理 WRITE 事件以进行高效的数据发送。
main.dart
import 'dart:io';
void main() async {
var socket = await RawSocket.connect('localhost', 8080);
var messages = ['Hello', 'World', 'From', 'Dart'];
var index = 0;
socket.listen((event) {
if (event == RawSocketEvent.write && index < messages.length) {
socket.write(messages[index++].codeUnits);
print('Sent: ${messages[index-1]}');
}
if (index == messages.length) {
socket.shutdown(SocketDirection.send);
}
});
socket.writeEventsEnabled = true;
}
我们仅在套接字准备好写入时才发送消息。WRITE 事件指示套接字何时可以接受更多数据而不阻塞。
$ dart main.dart Sent: Hello Sent: World Sent: From Sent: Dart
错误事件处理
此示例演示了处理套接字上的错误事件。
main.dart
import 'dart:io';
void main() async {
try {
var socket = await RawSocket.connect('invalid.host', 80);
socket.listen((event) {
if (event == RawSocketEvent.read) {
print('Data received');
} else if (event == RawSocketEvent.closed) {
print('Connection closed');
} else if (event == RawSocketEvent.readError ||
event == RawSocketEvent.writeError) {
print('Error occurred on socket');
socket.close();
}
});
} on SocketException catch (e) {
print('Connection failed: ${e.message}');
}
}
我们处理连接错误和运行时套接字错误。错误事件指示套接字连接或操作存在问题。
$ dart main.dart Connection failed: Failed host lookup: 'invalid.host'
完整的 Socket 客户端
此示例展示了一个具有所有事件类型的完整套接字客户端。
main.dart
import 'dart:io';
import 'dart:convert';
void main() async {
try {
var socket = await RawSocket.connect('example.com', 80);
var request = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n';
socket.listen((event) {
switch (event) {
case RawSocketEvent.read:
var data = socket.read();
if (data != null) {
print(utf8.decode(data.take(100)));
}
break;
case RawSocketEvent.write:
socket.write(request.codeUnits);
socket.writeEventsEnabled = false;
break;
case RawSocketEvent.closed:
print('Connection closed by server');
socket.close();
break;
case RawSocketEvent.readError:
case RawSocketEvent.writeError:
print('Socket error occurred');
socket.close();
break;
}
});
socket.writeEventsEnabled = true;
} on SocketException catch (e) {
print('Connection error: ${e.message}');
}
}
此完整示例处理所有套接字事件:初始写入、读取响应数据以及在关闭或错误时进行适当的清理。
$ dart main.dart HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Content-Length: 1256 ... Connection closed by server
最佳实践
- 启用事件: 仅在需要时设置 writeEventsEnabled
- 错误处理: 始终处理错误和关闭事件
- 资源清理:完成后关闭套接字
- 缓冲区管理: 在 READ 事件上读取所有可用数据
- 节流: 使用 WRITE 事件控制写入速率
来源
本教程涵盖了 Dart 的 RawSocketEvent 类,并通过实际示例展示了套接字编程的事件处理、数据传输和错误管理。
作者
列出 所有 Dart 教程。