Flutter以太网通信插件l2ethernet的使用
Flutter以太网通信插件l2ethernet的使用
插件介绍
这个小Dart包允许发送原始的以太网帧。我的用例是向一个名为Colorlight 5A接收卡发送数据,它期望接收到以太网帧,但我在Dart中找不到实现该功能的方法。误导性命名的RawSocket类实际上使用了TCP。
因此,这个包诞生了:通过FFI(C互操作),它使用Linux的socket()接口来发送原始以太网帧。可以用来发送任意以太网数据包,如WOL数据包、ARP欺骗、自定义协议等。
测试
测试包含两部分:一部分可以在非root用户下运行,另一部分需要root权限(或其他类似权限)因为它实际打开了一个原始套接字。我使用tcpdump在后台捕获发送的以太网数据包,并验证其是否符合预期。
编译共享库
这其实很简单,因为C层非常短。我添加了一个buildme.sh脚本。它非常简单。
macOS, Windows, Android, iOS
对不起,这些平台不在我支持范围内。
限制
- 目前不支持接收帧。
- 这不是性能优化的:单个帧同步发送出去。如果需要性能,应该使用sendmmsg()。
- 只支持Linux,并且共享库仅适用于x86_64和aarch64。编译这个库非常简单(参见buildme.sh)。
关于libeth.so的说明
当Dart编译为exe或AOT时,它不会查看packages,因此无法找到libeth.so。虽然将它静态链接到可执行文件或AOT文件中会很好,但在Dart 2.16.1版本中这并不工作。解决方法是将所需的libeth.so文件放在./lib/$march/libeth.so中,其中.是二进制文件的路径(例如sendframe.exe)。
示例代码
示例代码介绍
我添加了两个示例:
- send_packet.dart:展示如何发送一个简单的原始以太网帧。使用
tcpdump -i $nic 'ether proto 0xbeef'
可以看到它被发送出去。 - colorlight.dart:发送几个帧用于Colorlight卡。用于测试此包。
注意事项
- 两个示例都需要设置环境变量
nic
,包含要使用的网络接口名称。 - 两个示例都需要以root身份运行,或者二进制文件需要具备使用原始套接字的权限:
setcap 'cap_net_admin,cap_net_raw+ep' BINARY
- 由于需要以root身份运行,我强烈建议编译独立的可执行文件(通过
dart compile exe
),这样可以给它们添加上述权限。这避免了需要以root身份运行dart。
完整示例Demo
send_packet.dart
import 'package:l2ethernet/l2ethernet.dart';
void main() {
// 设置网络接口名称
final String nic = Platform.environment['nic'];
if (nic == null) {
print('Please set the "nic" environment variable.');
return;
}
// 创建以太网帧
final EthernetFrame frame = EthernetFrame(
destination: MacAddress.fromHex('ff:ff:ff:ff:ff:ff'), // 广播地址
source: MacAddress.fromHex('00:11:22:33:44:55'), // 源MAC地址
etherType: 0xbeef, // 自定义以太网类型
payload: Uint8List.fromList([1, 2, 3, 4]), // 载荷
);
// 发送以太网帧
final L2Ethernet l2Ethernet = L2Ethernet(nic);
l2Ethernet.send(frame);
print('Sent Ethernet frame!');
}
colorlight.dart
import 'package:l2ethernet/l2ethernet.dart';
void main() {
// 设置网络接口名称
final String nic = Platform.environment['nic'];
if (nic == null) {
print('Please set the "nic" environment variable.');
return;
}
// 创建以太网帧
final EthernetFrame frame = EthernetFrame(
destination: MacAddress.fromHex('ff:ff:ff:ff:ff:ff'), // 广播地址
source: MacAddress.fromHex('00:11:22:33:44:55'), // 源MAC地址
etherType: 0xbeef, // 自定义以太网类型
payload: Uint8List.fromList([1, 2, 3, 4]), // 载荷
);
// 发送多个以太网帧
final L2Ethernet l2Ethernet = L2Ethernet(nic);
for (int i = 0; i < 5; i++) {
l2Ethernet.send(frame);
print('Sent Ethernet frame $i!');
}
}
更多关于Flutter以太网通信插件l2ethernet的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter以太网通信插件l2ethernet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
l2ethernet
是一个用于在 Flutter 应用中进行以太网通信的插件。它允许应用直接在低层级(L2,数据链路层)与以太网设备进行通信。以下是使用 l2ethernet
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 l2ethernet
插件的依赖:
dependencies:
flutter:
sdk: flutter
l2ethernet: ^0.0.1 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入包
在你的 Dart 文件中导入 l2ethernet
包:
import 'package:l2ethernet/l2ethernet.dart';
3. 初始化以太网连接
使用 L2Ethernet
类来初始化和配置以太网连接。以下是一个简单的示例:
void main() async {
// 初始化 L2Ethernet
L2Ethernet l2Ethernet = L2Ethernet();
// 打开以太网接口
bool isOpened = await l2Ethernet.open("eth0"); // eth0 是以太网接口名称
if (isOpened) {
print("以太网接口打开成功");
// 发送数据
List<int> data = [0x01, 0x02, 0x03, 0x04];
await l2Ethernet.send(data);
print("数据发送成功");
// 接收数据
List<int> receivedData = await l2Ethernet.receive();
print("接收到的数据: $receivedData");
// 关闭以太网接口
await l2Ethernet.close();
print("以太网接口已关闭");
} else {
print("无法打开以太网接口");
}
}
4. 处理接收数据
receive
方法返回一个 List<int>
,表示接收到的字节数据。你可以根据需要进行解析和处理。
5. 关闭连接
使用 close
方法来关闭以太网接口,以释放资源。
6. 权限与配置
在某些平台上(如 Android),使用以太网功能可能需要特定的权限和配置。确保你在 AndroidManifest.xml
文件中添加了必要的权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>