# FTP 服务器设计与实现报告 ## 项目概述 ### 设计题目 **编程实现 FTP 服务器 ★★★** ### 设计要求 1. 客户端通过 Windows 的命令行访问 FTP 服务器 2. FTP 服务器可以并发地服务多个客户 3. 至少实现对 FTP 命令 user、pass、dir、get 的支持 4. FTP 服务器必须对出现的问题或错误做出响应 ### 技术栈 - **编程语言**: Python 3.13+ - **网络编程**: Socket 编程 - **并发处理**: Threading 多线程 - **协议标准**: RFC 959 FTP 协议 ## 系统架构设计 ### 整体架构 ```mermaid graph TB A[Windows FTP Client] --> B[FTP Server Main] B --> C[Control Connection Handler] B --> D[Threading Manager] C --> E[Command Parser] C --> F[Data Connection Manager] E --> G[User Authentication] E --> H[File Operations] F --> I[Active Mode] F --> J[Passive Mode] D --> K[Client Thread 1] D --> L[Client Thread 2] D --> M[Client Thread N] style A fill:#e1f5fe style B fill:#f3e5f5 style C fill:#e8f5e8 style D fill:#fff3e0 ``` ### 类设计图 ```mermaid classDiagram class FTPServer { +host: str +port: int +server_socket: socket +running: bool +client_threads: list +start_server() +handle_client() +stop_server() +cleanup_threads() } class FTPSession { +client_socket: socket +client_address: tuple +data_socket: socket +authenticated: bool +username: str +current_directory: str +handle_session() +handle_command() +send_response() } class CommandHandler { +handle_user() +handle_pass() +handle_list() +handle_retr() +handle_pwd() +handle_cwd() +handle_pasv() +handle_port() } FTPServer --> FTPSession FTPSession --> CommandHandler ``` ### 数据流图 ```mermaid sequenceDiagram participant Client as Windows FTP Client participant Server as FTP Server participant Session as FTP Session participant Auth as Authentication participant FileOp as File Operations Client->>Server: TCP Connection (Port 21) Server->>Session: Create New Session Session->>Client: 220 Service Ready Client->>Session: USER username Session->>Auth: Validate User Auth->>Session: User OK Session->>Client: 331 Password Required Client->>Session: PASS password Session->>Auth: Authenticate Auth->>Session: Login Success Session->>Client: 230 User Logged In Client->>Session: LIST Session->>Client: 150 Opening Data Connection Session->>FileOp: Get Directory Listing FileOp->>Session: File List Session->>Client: Directory Data Session->>Client: 226 Transfer Complete Client->>Session: RETR filename Session->>Client: 150 Opening Data Connection Session->>FileOp: Read File FileOp->>Session: File Data Session->>Client: File Data Session->>Client: 226 Transfer Complete ``` ## FTP 协议分析 ### RFC 959 标准 FTP (File Transfer Protocol) 是基于 TCP 的应用层协议,使用两个连接: - **控制连接** (端口 21): 传输命令和响应 - **数据连接**: 传输文件数据和目录列表 ### 支持的 FTP 命令 | 命令 | 功能 | 实现状态 | |------|------|----------| | USER | 用户身份验证 | ✅ 已实现 | | PASS | 密码验证 | ✅ 已实现 | | LIST | 目录列表 (对应 DIR) | ✅ 已实现 | | NLST | 简单文件列表 | ✅ 已实现 | | RETR | 文件下载 (对应 GET) | ✅ 已实现 | | PWD | 显示当前目录 | ✅ 已实现 | | CWD | 改变目录 | ✅ 已实现 | | PASV | 被动模式 | ✅ 已实现 | | PORT | 主动模式 | ✅ 已实现 | | TYPE | 传输类型 | ✅ 已实现 | | SYST | 系统信息 | ✅ 已实现 | | QUIT | 退出连接 | ✅ 已实现 | ### FTP 响应码 ```mermaid graph LR A[FTP 响应码] --> B[2xx 成功] A --> C[3xx 需要更多信息] A --> D[4xx 临时错误] A --> E[5xx 永久错误] B --> B1[220 服务就绪] B --> B2[230 用户登录成功] B --> B3[226 传输完成] C --> C1[331 需要密码] D --> D1[425 无法打开数据连接] E --> E1[530 未登录] E --> E2[550 文件不存在] ``` ## 核心模块设计 ### 1. 配置模块 (config.py) ```python # 服务器配置 FTP_HOST = '127.0.0.1' FTP_PORT = 21 DATA_PORT_RANGE = (20000, 20100) # 用户认证 USERS = { 'admin': 'admin123', 'user': 'password', 'test': 'test123', 'guest': 'guest' } # FTP 响应码 FTP_RESPONSES = { '220': '220 Service ready for new user.', '230': '230 User logged in, proceed.', '331': '331 User name okay, need password.', # ... 更多响应码 } ``` ### 2. 主服务器模块 (ftp_server.py) - **多线程处理**: 每个客户端连接创建独立线程 - **信号处理**: 优雅关闭服务器 - **连接管理**: 管理活跃连接和线程清理 ### 3. 会话处理模块 (ftp_session.py) - **命令解析**: 解析和路由 FTP 命令 - **状态管理**: 维护用户认证状态和当前目录 - **数据传输**: 处理被动/主动模式数据连接 ## 关键技术实现 ### 1. 多线程并发处理 ```mermaid graph TD A[主服务器线程] --> B[监听端口 21] B --> C[接受客户端连接] C --> D[创建客户端线程] D --> E[FTP 会话处理] E --> F[命令处理循环] F --> G[响应客户端] G --> F F --> H[连接关闭] H --> I[线程结束] style A fill:#ffeb3b style D fill:#4caf50 style E fill:#2196f3 ``` ### 2. 用户认证机制 ```mermaid stateDiagram-v2 [*] --> 未认证 未认证 --> 用户名验证 : USER command 用户名验证 --> 密码验证 : PASS command 密码验证 --> 已认证 : 认证成功 密码验证 --> 未认证 : 认证失败 已认证 --> 未认证 : QUIT command 已认证 --> [*] : 连接断开 ``` ### 3. 数据连接管理 #### 被动模式 (PASV) ```python def handle_pasv(self): # 创建数据监听套接字 self.passive_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定到可用端口 for port in range(DATA_PORT_RANGE[0], DATA_PORT_RANGE[1]): try: self.passive_socket.bind(('127.0.0.1', port)) break except OSError: continue # 返回 PASV 响应 p1 = port // 256 p2 = port % 256 self.send_response('227', f'Entering Passive Mode (127,0,0,1,{p1},{p2})') ``` #### 主动模式 (PORT) ```python def handle_port(self, args): # 解析 PORT 命令参数 parts = args.split(',') ip = '.'.join(parts[:4]) port = int(parts[4]) * 256 + int(parts[5]) # 保存客户端数据连接地址 self.data_address = (ip, port) ``` ### 4. 文件传输实现 #### 目录列表 (LIST/DIR) ```python def handle_list(self, command): # 建立数据连接 if not self.establish_data_connection(): return # 获取目录内容 files = os.listdir(self.current_directory) listing = [] for filename in files: if command == 'LIST': # 详细列表格式 stat = os.stat(filepath) listing.append(f'{permissions} {size} {mtime} {filename}') else: # 简单列表格式 listing.append(filename) # 发送数据 data = '\r\n'.join(listing) + '\r\n' self.data_socket.send(data.encode('utf-8')) ``` #### 文件下载 (RETR/GET) ```python def handle_retr(self, filename): # 安全检查 filepath = os.path.normpath(os.path.join(self.current_directory, filename)) if not filepath.startswith(SERVER_ROOT): self.send_response('550', 'Permission denied') return # 建立数据连接 if not self.establish_data_connection(): return # 传输文件 with open(filepath, 'rb') as f: while True: data = f.read(8192) if not data: break self.data_socket.send(data) ``` ## 安全性设计 ### 1. 路径安全 - **路径规范化**: 使用 `os.path.normpath()` 防止路径遍历 - **根目录限制**: 确保所有文件操作在服务器根目录内 - **权限检查**: 验证文件访问权限 ### 2. 用户认证 - **密码验证**: 简单的用户名/密码认证机制 - **会话管理**: 维护用户登录状态 - **权限控制**: 未认证用户无法执行文件操作 ### 3. 错误处理 - **异常捕获**: 全面的异常处理机制 - **错误响应**: 标准 FTP 错误码响应 - **资源清理**: 确保连接和文件句柄正确关闭 ## 测试方案 ### 1. 功能测试 #### Windows 命令行测试 ```cmd # 连接到 FTP 服务器 ftp 127.0.0.1 # 用户认证 USER admin PASS admin123 # 目录操作 PWD DIR CD documents # 文件下载 GET readme.txt GET sample.txt # 退出 QUIT ``` ### 2. 并发测试 - 多个客户端同时连接 - 并发文件传输测试 - 线程安全验证 ### 3. 错误处理测试 - 无效用户名/密码 - 不存在的文件/目录 - 网络连接中断 - 权限拒绝场景 ## 项目文件结构 ``` CN-design-ftp/ ├── main.py # 程序入口 ├── ftp_server.py # 主服务器类 ├── ftp_session.py # 会话处理类 ├── config.py # 配置文件 ├── design_report.md # 设计报告 ├── ftp_root/ # FTP 服务器根目录 │ ├── readme.txt # 说明文件 │ ├── sample.txt # 示例文本文件 │ ├── data.json # JSON 数据文件 │ └── documents/ # 子目录 │ └── test_doc.txt # 测试文档 └── test_files/ # 测试文件目录 ``` ## 使用说明 ### 1. 启动服务器 ```bash python main.py ``` ### 2. Windows 客户端连接 ```cmd ftp 127.0.0.1 2121 ``` 注意:由于使用非标准端口 2121(避免需要管理员权限),需要指定端口号。 ### 3. 测试用户账号 | 用户名 | 密码 | |--------|------| | admin | admin123 | | user | password | | test | test123 | | guest | guest | ### 4. 支持的命令映射 | Windows FTP 命令 | FTP 协议命令 | 功能 | |------------------|--------------|------| | USER username | USER | 用户登录 | | PASS password | PASS | 密码验证 | | DIR | LIST | 目录列表 | | LS | NLST | 简单列表 | | GET filename | RETR | 下载文件 | | PWD | PWD | 当前目录 | | CD dirname | CWD | 改变目录 | | QUIT | QUIT | 退出连接 | ## 性能特点 ### 1. 并发性能 - **多线程架构**: 支持多客户端并发访问 - **线程池管理**: 自动清理完成的线程 - **资源优化**: 合理的端口范围和连接管理 ### 2. 可扩展性 - **模块化设计**: 清晰的模块分离 - **配置化**: 易于修改服务器参数 - **命令扩展**: 容易添加新的 FTP 命令 ### 3. 稳定性 - **异常处理**: 全面的错误处理机制 - **优雅关闭**: 信号处理和资源清理 - **状态管理**: 可靠的会话状态维护 ## 技术难点与解决方案 ### 1. FTP 协议的双连接机制 **难点**: FTP 使用控制连接和数据连接分离的设计 **解决方案**: - 实现被动模式 (PASV) 和主动模式 (PORT) - 动态端口分配和连接管理 - 数据传输完成后及时关闭数据连接 ### 2. 多线程并发处理 **难点**: 多客户端并发访问的线程安全 **解决方案**: - 每个客户端独立线程处理 - 线程安全的资源管理 - 优雅的线程生命周期管理 ### 3. Windows 兼容性 **难点**: 确保与 Windows FTP 客户端完全兼容 **解决方案**: - 严格遵循 RFC 959 标准 - 正确的响应码和消息格式 - 支持 Windows FTP 客户端的命令映射 ## 总结 本项目成功实现了一个功能完整的 FTP 服务器,满足了所有设计要求: 1. ✅ **Windows 命令行兼容**: 完全支持 Windows FTP 客户端 2. ✅ **并发处理**: 多线程架构支持多客户端同时访问 3. ✅ **核心命令支持**: 实现了 USER、PASS、DIR、GET 等关键命令 4. ✅ **错误处理**: 完善的错误响应和异常处理机制 ### 技术亮点 - 严格遵循 RFC 959 FTP 协议标准 - 模块化和可扩展的代码架构 - 全面的安全性考虑 - 详细的文档和测试方案 ### 学习收获 - 深入理解了 FTP 协议的工作原理 - 掌握了 Python Socket 网络编程 - 学会了多线程并发编程技术 - 提高了系统设计和架构能力 该 FTP 服务器可以作为计算机网络课程设计的优秀示例,展示了网络协议实现的完整过程。