Flutter SSH连接插件dartssh3的使用
Flutter SSH连接插件dartssh3的使用
简介
dartssh3 是一个用纯 Dart 编写的 SSH 和 SFTP 客户端库。它旨在功能丰富且易于使用,同时支持 Dart VM 和 Flutter 平台。
dartssh3 是对 dartssh2 的分支,因为原作者停止了开发。
✨ 特性
- Pure Dart: 支持在 Dart VM 和 Flutter 中运行。
- SSH Session: 支持执行命令、启动 shell、设置环境变量、伪终端等。
- Authentication: 支持密码、私钥和交互式认证方法。
- Forwarding: 支持本地转发和远程转发。
- SFTP: 支持所有定义在 SFTPv3 协议 中的操作,包括上传、下载、列表、链接、删除、重命名等。
🧱 构建工具
以下是一些使用 dartssh3 构建的应用:
应用名称 | 描述 |
---|---|
ServerBox | 提供服务器管理和监控界面,支持通过 dartssh3 连接远程服务器。 |
![]() |
ServerBox 的界面展示连接管理选项。 |
![]() |
ServerBox 的用户界面,用于服务器控制和监控。 |
Ssh! No Ports | 展示通过 dartssh3 实现无开放端口的 SSH 连接。 |
![]() |
Ssh! No Ports 的演示,无需开放端口即可实现 SSH 连接。 |
DartShell | 显示终端和会话信息以支持 SSH 操作。 |
![]() |
DartShell 的终端界面展示。 |
欢迎通过 Pull Request 添加您的应用!
🧪 尝试
安装 dartssh
命令行工具:
# 安装 `dartssh` 命令。
dart pub global activate dartssh2_cli
# 使用 `dartssh` 像普通 `ssh` 命令一样。
dartssh user@example.com
# 示例:在远程主机上执行命令。
dartssh user@example.com ls -al
# 示例:连接到非标准端口。
dartssh user@example.com:<port>
# 使用 SFTP 传输文件。
dartsftp user@example.com
如果安装后无法找到 dartssh
命令,请确保设置好路径:设置路径指南。
🚀 快速开始
连接到远程主机
final client = SSHClient(
await SSHSocket.connect('localhost', 22),
username: '<username>',
onPasswordRequest: () => '<password>',
);
<code>SSHSocket</code>
是一个接口,您可以根据需要实现自定义的<code>SSHSocket</code>
,例如使用 WebSocket 或 Unix 域套接字作为底层传输。
启动远程主机上的 shell
final shell = await client.shell();
stdout.addStream(shell.stdout); // 监听标准输出
stderr.addStream(shell.stderr); // 监听错误输出
stdin.cast<Uint8List>().listen(shell.write); // 写入标准输入
await shell.done; // 等待 shell 退出
client.close();
在远程主机上执行命令
final uptime = await client.run('uptime');
print(utf8.decode(uptime));
忽略标准错误:
final uptime = await client.run('uptime', stderr: false);
print(utf8.decode(uptime));
<code>client.run()</code>
是一个便捷方法,用于包装<code>client.execute()</code>
来运行非交互式命令。
在远程主机上启动进程
final session = await client.execute('cat > file.txt');
await session.stdin.addStream(File('local_file.txt').openRead().cast());
await session.stdin.close(); // 关闭流以发送 EOF 给远程进程。
await session.done; // 等待会话完成,确保所有数据都已刷新到远程进程。
print(session.exitCode); // 会话完成后可以获取退出码
推荐使用
<code>session.stdin.addStream()</code>
而不是<code>session.write()</code>
,特别是在传输大量数据时。
通过信号终止远程进程
session.kill(SSHSignal.KILL);
await session.done;
print('exitCode: ${session.exitCode}'); // -> exitCode: null
print('signal: ${session.exitSignal?.signalName}'); // -> signal: KILL
被信号终止的进程没有退出码,而是有退出信号属性。
本地端口转发(将本地端口 8080 转发到服务器)
final serverSocket = await ServerSocket.bind('localhost', 8080);
await for (final socket in serverSocket) {
final forward = await client.forwardLocal('httpbin.org', 80);
forward.stream.cast<List<int>>().pipe(socket);
socket.pipe(forward.sink);
}
远程端口转发(将服务器的 2222 端口转发到本地 22 端口)
final forward = await client.forwardRemote(port: 2222);
if (forward == null) {
print('Failed to forward remote port');
return;
}
await for (final connection in forward.connections) {
final socket = await Socket.connect('localhost', 22);
connection.stream.cast<List<int>>().pipe(socket);
socket.pipe(connection.sink);
}
使用公钥进行身份验证
final client = SSHClient(
socket,
username: '<username>',
identities: [
// 单个私钥文件可能包含多个密钥。
...SSHKeyPair.fromPem(await File('path/to/id_rsa').readAsString())
],
);
使用加密的 PEM 文件
// 测试私钥是否加密。
final encrypted = SSHKeyPair.isEncrypted(await File('path/to/id_rsa').readAsString());
print(encrypted);
// 如果私钥加密,则需要提供密码短语。
final keys = SSHKeyPair.fromPem('<pem text>', '<passphrase>');
print(keys);
在 Flutter 中解密 PEM 文件:
List<SSHKeyPair> decryptKeyPairs(List<String> args) {
return SSHKeyPair.fromPem(args[0], args[1]);
}
final keypairs = await compute(decryptKeyPairs, ['<pem text>', '<passphrase>']);
获取 SSH 服务器版本
await client.authenticated;
print(client.remoteVersion); // SSH-2.0-OpenSSH_7.4p1
通过跳板机连接
final jumpServer = SSHClient(
await SSHSocket.connect('<jump server>', 22),
username: '...',
onPasswordRequest: () => '...',
);
final client = SSHClient(
await jumpServer.forwardLocal('<target server>', 22),
username: '...',
onPasswordRequest: () => '...',
);
print(utf8.decode(await client.run('hostname'))); // -> <target server> 的主机名
SFTP
列出远程目录
final sftp = await client.sftp();
final items = await sftp.listdir('/');
for (final item in items) {
print(item.longname);
}
读取远程文件
final sftp = await client.sftp();
final file = await sftp.open('/etc/passwd');
final content = await file.readBytes();
print(latin1.decode(content));
写入远程文件
final sftp = await client.sftp();
final file = await sftp.open('file.txt', mode: SftpFileOpenMode.write);
await file.writeBytes(utf8.encode('hello there!') as Uint8List);
在特定偏移处写入数据
final data = utf8.encode('world') as Uint8List;
await file.writeBytes(data, offset: 6);
文件上传
final sftp = await client.sftp();
final file = await sftp.open('file.txt', mode: SftpFileOpenMode.create | SftpFileOpenMode.write);
await file.write(File('local_file.txt').openRead().cast());
暂停和恢复文件上传
final uploader = await file.write(File('local_file.txt').openRead().cast());
// ...
await uploader.pause();
// ...
await uploader.resume();
await uploader.done;
清空远程文件再打开
final file = await sftp.open('file.txt',
mode: SftpFileOpenMode.create | SftpFileOpenMode.truncate | SftpFileOpenMode.write
);
目录操作
final sftp = await client.sftp();
await sftp.mkdir('/path/to/dir');
await sftp.rmdir('/path/to/dir');
获取/设置远程文件/目录的属性
await sftp.stat('/path/to/file');
await sftp.setStat(
'/path/to/file',
SftpFileAttrs(mode: SftpFileMode(userRead: true)),
);
获取远程文件类型
final stat = await sftp.stat('/path/to/file');
print(stat.type);
// 或者
print(stat.isDirectory);
print(stat.isSocket);
print(stat.isSymbolicLink);
// ...
创建链接
final sftp = await client.sftp();
sftp.link('/from', '/to');
获取远程文件系统总空间和可用空间
final sftp = await client.sftp();
final statvfs = await sftp.statvfs('/root');
print('total: ${statvfs.blockSize * statvfs.totalBlocks}');
print('free: ${statvfs.blockSize * statvfs.freeBlocks}');
示例代码
以下是完整的示例代码,展示如何使用 dartssh3 连接到远程主机并执行命令。
示例代码:SSH Client
import 'dart:convert';
import 'dart:io';
import 'package:dartssh3/dartssh3.dart';
void main(List<String> args) async {
// 连接到远程主机
final socket = await SSHSocket.connect('localhost', 22);
final client = SSHClient(
socket,
username: 'root',
onPasswordRequest: () {
stdout.write('Password: ');
stdin.echoMode = false;
return stdin.readLineSync() ?? exit(1);
},
);
// 执行命令并打印结果
final uptime = await client.run('uptime');
print(utf8.decode(uptime));
// 关闭客户端
client.close();
await client.done;
}
更多关于Flutter SSH连接插件dartssh3的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter SSH连接插件dartssh3的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dartssh3
是一个用于在 Flutter 应用中实现 SSH 连接的插件。它基于 dartssh
库,提供了 SSH 客户端功能,允许你在 Flutter 应用中执行远程命令、传输文件等操作。
以下是如何在 Flutter 项目中使用 dartssh3
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 dartssh3
依赖:
dependencies:
flutter:
sdk: flutter
dartssh3: ^0.0.1 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入库
在你的 Dart 文件中导入 dartssh3
库:
import 'package:dartssh3/dartssh3.dart';
3. 创建 SSH 连接
使用 SSHClient
类来创建 SSH 连接。你需要提供远程主机的地址、端口、用户名和密码(或私钥)。
void connectToSSH() async {
final client = SSHClient(
host: 'your.remote.host',
port: 22,
username: 'your_username',
passwordOrKey: 'your_password', // 或者使用私钥
);
try {
await client.connect();
print('Connected to SSH server');
// 执行远程命令
final result = await client.execute('ls -la');
print('Command result: $result');
// 关闭连接
await client.disconnect();
print('Disconnected from SSH server');
} catch (e) {
print('Failed to connect: $e');
}
}
4. 执行远程命令
使用 execute
方法可以在远程服务器上执行命令,并获取命令的输出。
final result = await client.execute('ls -la');
print('Command result: $result');
5. 文件传输
dartssh3
也支持文件传输。你可以使用 scp
方法来上传或下载文件。
// 上传文件
await client.scpUpload('local_file.txt', 'remote_file.txt');
// 下载文件
await client.scpDownload('remote_file.txt', 'local_file.txt');
6. 关闭连接
完成操作后,记得关闭 SSH 连接。
await client.disconnect();
7. 处理异常
在实际使用中,可能会遇到各种异常情况,如连接失败、认证失败等。确保在代码中处理这些异常。
try {
await client.connect();
// 其他操作
} catch (e) {
print('Error: $e');
} finally {
await client.disconnect();
}
8. 使用私钥认证
如果你使用私钥进行认证,可以将私钥文件的内容传递给 passwordOrKey
参数。
final client = SSHClient(
host: 'your.remote.host',
port: 22,
username: 'your_username',
passwordOrKey: '-----BEGIN RSA PRIVATE KEY-----\n...', // 私钥内容
);
9. 完整示例
以下是一个完整的示例,展示了如何使用 dartssh3
进行 SSH 连接、执行命令和文件传输。
import 'package:dartssh3/dartssh3.dart';
void main() async {
final client = SSHClient(
host: 'your.remote.host',
port: 22,
username: 'your_username',
passwordOrKey: 'your_password', // 或者使用私钥
);
try {
await client.connect();
print('Connected to SSH server');
// 执行远程命令
final result = await client.execute('ls -la');
print('Command result: $result');
// 上传文件
await client.scpUpload('local_file.txt', 'remote_file.txt');
print('File uploaded');
// 下载文件
await client.scpDownload('remote_file.txt', 'local_file.txt');
print('File downloaded');
// 关闭连接
await client.disconnect();
print('Disconnected from SSH server');
} catch (e) {
print('Error: $e');
} finally {
await client.disconnect();
}
}