Flutter FTP服务器搭建插件ftp_server的使用
Flutter FTP服务器搭建插件 ftp_server
的使用
ftp_server
是一个用于在 Dart 中实现简单 FTP 服务器的包。它支持读写和只读模式,适用于各种用例。该服务器允许客户端连接并执行标准的 FTP 操作,如列出目录、检索文件、存储文件等。
特性
- 被动和主动模式:支持被动和主动数据连接。
- 文件操作:检索、存储、删除和列出文件。
- 目录操作:更改、创建和删除目录。
- 只读模式:禁用写操作以增强安全性。
- 身份验证:基本用户名和密码身份验证。
兼容性
该包已在 macOS 上进行了测试。对于 Linux 和 Windows,已实现 CI/CD 测试用例,以确保代码运行和功能正常。
使用方法
启动服务器
以下是如何启动 FTP 服务器的示例:
import 'package:ftp_server/ftp_server.dart';
void main() async {
final server = FtpServer(
port: 21,
username: 'user',
password: 'pass',
sharedDirectories: ['/home/user/ftp'],
startingDirectory: 'ftp',
serverType: ServerType.readAndWrite, // 或者 ServerType.readOnly
);
await server.start();
}
支持的操作
服务器支持以下 FTP 命令:
命令 | 描述 |
---|---|
USER <username> |
设置用户名进行身份验证。 |
PASS <password> |
设置密码进行身份验证。 |
QUIT |
关闭控制连接。 |
PASV |
进入被动模式。 |
PORT <host-port> |
进入主动模式。 |
LIST [<directory>] |
列出指定目录或当前目录中的文件。 |
RETR <filename> |
检索指定文件。 |
STOR <filename> |
存储文件。 |
CWD <directory> |
更改当前目录。 |
CDUP |
更改为父目录。 |
MKD <directory> |
创建新目录。 |
RMD <directory> |
删除目录。 |
DELE <filename> |
删除文件。 |
PWD |
打印当前目录。 |
SYST |
返回系统类型。 |
NOOP |
不执行任何操作(用于保持连接)。 |
SIZE <filename> |
返回指定文件的大小。 |
身份验证
要启用身份验证,在创建 FtpServer
实例时提供 username
和 password
参数。然后,服务器将要求客户端使用这些凭据登录。
只读模式
要以只读模式运行服务器,将 serverType
参数设置为 ServerType.readOnly
。在此模式下,修改文件系统的命令(例如 STOR
、DELE
、MKD
、RMD
)将被禁用。
示例 Demo
下面是一个完整的 Flutter 应用程序示例,演示如何使用 ftp_server
包来启动和停止 FTP 服务器,并选择共享目录。
// ignore_for_file: avoid_print
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:ftp_server/ftp_server.dart';
import 'package:ftp_server/server_type.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
FtpServer? ftpServer;
String serverStatus = 'Server is not running';
String connectionInfo = 'No connection info';
String directoryPath = 'No directory chosen';
bool isLoading = false;
Isolate? isolate;
ReceivePort? receivePort;
int? port;
@override
void initState() {
super.initState();
if (Platform.isAndroid) {
_requestPermission();
}
_loadDirectory();
}
Future<void> _requestPermission() async {
if (await Permission.manageExternalStorage.isDenied) {
await Permission.manageExternalStorage.request();
}
}
Future<void> _loadDirectory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? savedDirectory = prefs.getString('serverDirectory');
if (savedDirectory != null) {
setState(() {
directoryPath = savedDirectory;
});
}
}
Future<String?> getIpAddress() async {
// Implement your method to get device IP address here
return '192.168.1.100'; // Example IP address
}
Future<String?> pickDirectory() async {
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();
if (selectedDirectory != null) {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('serverDirectory', selectedDirectory);
setState(() {
directoryPath = selectedDirectory;
});
}
return selectedDirectory;
}
Future<void> toggleServer() async {
setState(() {
isLoading = true;
});
if (ftpServer == null) {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? serverDirectory = prefs.getString('serverDirectory');
if (serverDirectory == null) {
serverDirectory = await pickDirectory();
if (serverDirectory != null) {
await prefs.setString('serverDirectory', serverDirectory);
} else {
setState(() {
isLoading = false;
});
return;
}
}
var server = FtpServer(
port ?? Random().nextInt(65535),
sharedDirectories: [serverDirectory],
serverType: ServerType.readAndWrite,
logFunction: (p0) => print(p0),
);
Future serverFuture = server.start();
ftpServer = server;
var address = await getIpAddress();
setState(() {
serverStatus = 'Server is running';
connectionInfo = 'Connect using FTP client:\nftp://$address:${server.port}';
isLoading = false;
});
await serverFuture;
} else {
await ftpServer!.stop();
ftpServer = null;
setState(() {
serverStatus = 'Server is not running';
connectionInfo = 'No connection info';
isLoading = false;
});
}
}
@override
void dispose() {
receivePort?.close();
isolate?.kill(priority: Isolate.immediate);
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter FTP Server'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(serverStatus),
const SizedBox(height: 20),
Text(connectionInfo),
const SizedBox(height: 20),
Text('Directory: $directoryPath'),
const SizedBox(height: 20),
isLoading
? const CircularProgressIndicator()
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: toggleServer,
child: Text(
ftpServer == null ? 'Start Server' : 'Stop Server',
),
),
const SizedBox(width: 20),
ElevatedButton(
onPressed: pickDirectory,
child: const Text('Pick Directory'),
),
],
),
],
),
),
),
);
}
}
这个示例展示了如何在 Flutter 应用中集成 ftp_server
包,并提供了启动和停止 FTP 服务器的功能,同时还可以选择共享目录。
更多关于Flutter FTP服务器搭建插件ftp_server的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter FTP服务器搭建插件ftp_server的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中搭建FTP服务器并使用ftp_server
插件涉及到多个步骤,包括配置服务器、处理连接和传输文件等。虽然Flutter主要用于构建跨平台的移动应用,但可以通过使用Dart的VM(虚拟机)来运行服务器端的代码。以下是一个使用ftp_server
插件搭建FTP服务器的基本示例代码。
首先,你需要确保你的Flutter环境已经设置好,并且已经添加了ftp_server
依赖。在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
ftp_server: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
由于Flutter本身是为客户端应用设计的,我们将在Dart VM环境中运行这个示例。因此,你需要创建一个单独的Dart文件(例如ftp_server.dart
)来运行服务器代码。
ftp_server.dart
import 'dart:io';
import 'package:ftp_server/ftp_server.dart';
void main() async {
// 定义FTP服务器的配置
var config = FtpServerConfig(
ip: InternetAddress.anyIPv4, // 监听所有IPv4地址
port: 21, // FTP默认端口
anonymous: false, // 不允许匿名登录
userManager: InMemoryUserManager()
..addUser("user", "password", "/path/to/ftp/root"), // 添加用户及其密码和根目录
);
// 创建FTP服务器实例
var ftpServer = FtpServer(config);
// 启动服务器
await ftpServer.start();
print("FTP服务器已启动,监听端口 ${config.port}");
// 为了保持服务器运行,我们在这里使用一个简单的循环
stdin.listen((_) => null); // 等待用户输入以保持进程活跃(Ctrl+C停止服务器)
}
说明
- FtpServerConfig: 配置FTP服务器,包括监听IP、端口、是否允许匿名登录以及用户管理。
- InMemoryUserManager: 内存中的用户管理器,用于添加和管理用户。在这个例子中,我们添加了一个用户
user
,密码为password
,其根目录为/path/to/ftp/root
(请替换为实际的路径)。 - FtpServer: 创建FTP服务器实例。
- ftpServer.start(): 启动FTP服务器。
- stdin.listen((_) => null): 保持服务器运行,等待用户输入(在实际应用中,你可能会用更优雅的方式来管理服务器的生命周期)。
运行服务器
使用Dart VM运行ftp_server.dart
文件:
dart ftp_server.dart
注意事项
- 确保
/path/to/ftp/root
目录存在并且具有适当的读写权限。 - 由于FTP通常用于传输文件,因此确保防火墙设置允许从你的客户端到服务器的21端口的连接。
- 在生产环境中,你可能需要更复杂的用户管理和权限控制。
- 这个示例仅用于演示目的,实际应用中需要考虑更多的安全性和错误处理。
这样,你就搭建了一个基本的FTP服务器,并且可以使用FTP客户端(如FileZilla)连接到这个服务器,使用用户名user
和密码password
进行登录。