Dart RawSocket
最后修改于 2025 年 4 月 4 日
Dart 中的 RawSocket 类提供了低级的网络套接字通信功能。它允许直接进行 TCP/IP 套接字操作。
RawSocket 是 Dart 的 dart:io 库的一部分,与 HttpClient 或 WebSocket 等更高级的替代方案相比,它提供了更多的控制权。
基本定义
RawSocket 代表一个原始网络套接字连接。它在没有协议处理的情况下直接访问套接字事件和数据流。
主要功能包括基于事件的通信、直接字节流访问和细粒度的连接控制。它对于自定义协议很有用。
基本的 RawSocket 客户端
本示例展示了一个基本的 RawSocket 客户端连接到服务器。
import 'dart:io';
void main() async {
try {
var socket = await RawSocket.connect('example.com', 80);
print('Connected to ${socket.remoteAddress.address}');
socket.listen((event) {
if (event == RawSocketEvent.read) {
var data = socket.read();
print('Received: ${String.fromCharCodes(data)}');
}
});
socket.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'.codeUnits);
} catch (e) {
print('Error: $e');
}
}
我们连接到 example.com 的 80 端口创建一个 TCP 连接。listen 方法处理套接字事件。我们发送一个 HTTP 请求并打印响应。
$ dart main.dart Connected to 93.184.216.34 Received: HTTP/1.1 200 OK ...
处理多个套接字事件
本示例演示了如何处理不同的套接字事件。
import 'dart:io';
void main() async {
var socket = await RawSocket.connect('localhost', 8080);
socket.listen((event) {
switch (event) {
case RawSocketEvent.read:
var data = socket.read();
print('Data: ${String.fromCharCodes(data)}');
break;
case RawSocketEvent.write:
print('Ready to write');
break;
case RawSocketEvent.closed:
print('Connection closed');
break;
default:
print('Unknown event: $event');
}
});
socket.write('Hello server'.codeUnits);
await Future.delayed(Duration(seconds: 1));
socket.close();
}
我们分别处理 read、write 和 closed 事件。switch 语句将不同的套接字事件路由到适当的处理程序进行处理。
$ dart main.dart Ready to write Data: Hello client Connection closed
创建一个简单的回显服务器
本示例展示了一个使用 RawSocket 的基本回显服务器。
import 'dart:io';
void main() async {
var server = await ServerSocket.bind('127.0.0.1', 8080);
print('Listening on ${server.address.address}:${server.port}');
server.listen((client) {
client.listen((event) {
if (event == RawSocketEvent.read) {
var data = client.read();
print('Received: ${String.fromCharCodes(data)}');
client.write(data);
}
});
});
}
服务器绑定到 localhost 的 8080 端口。它将任何接收到的数据回显回去。每个客户端连接都有自己的事件监听器来处理消息。
$ dart server.dart Listening on 127.0.0.1:8080 Received: Test message
套接字超时处理
本示例演示了如何实现连接超时。
import 'dart:io';
import 'dart:async';
void main() async {
try {
var socket = await RawSocket.connect('example.com', 80)
.timeout(Duration(seconds: 3));
socket.listen((event) {
if (event == RawSocketEvent.read) {
print('Data received');
}
});
print('Connection successful');
} on TimeoutException {
print('Connection timed out');
} on SocketException catch (e) {
print('Socket error: $e');
}
}
我们在连接尝试中添加了 3 秒的超时。如果连接未及时建立,timeout 方法将抛出 TimeoutException。
$ dart main.dart Connection successful
二进制数据传输
本示例展示了如何发送和接收二进制数据。
import 'dart:io';
import 'dart:typed_data';
void main() async {
var socket = await RawSocket.connect('localhost', 9000);
// Send binary data
var bytes = Uint8List.fromList([0, 1, 2, 3, 255]);
socket.write(bytes);
socket.listen((event) {
if (event == RawSocketEvent.read) {
var response = socket.read();
print('Received bytes: $response');
}
});
await Future.delayed(Duration(seconds: 1));
socket.close();
}
我们创建一个包含二进制值的 Uint8List 并通过套接字发送它。套接字透明地处理二进制数据,无需任何转换。
$ dart main.dart Received bytes: [0, 1, 2, 3, 255]
最佳实践
- 错误处理:始终处理套接字异常
- 资源清理:完成后关闭套接字
- 缓冲:实现适当的数据缓冲
- 超时:设置合理的超时值
- 事件处理:处理所有相关的套接字事件
来源
本教程介绍了 Dart 的 RawSocket 类,并通过实际示例展示了基本用法、事件处理、二进制数据和服务器实现。
作者
列出 所有 Dart 教程。