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 教程。