对比如下:
| 特性维度 | FTP | SFTP | SCP | TFTP |
|---|---|---|---|---|
| 安全性 | 明文传输 | 基于SSH加密 | 基于SSH加密 | 无加密 |
| 默认端口 | 21 | 22 | 22 | 69 |
| 协议基础 | TCP | SSH | SSH | UDP |
| 认证方式 | 用户名/密码 | 多种(如公钥) | SSH认证 | 无认证 |
| 交互性 | 交互式命令 | 交互式命令 | 仅命令行 | 非交互式 |
| 目录操作 | 支持 | 支持 | 需-r递归 |
不支持 |
| 适用场景 | 内网、匿名访问 | 安全要求高的环境 | 简单文件复制 | 局域网内小文件、网络设备配置 |
ftp ip地址
输入用户名密码进入以后。
dir查看当前目录
put 可以put本地内容进当前目录
比如 put D:/1.txt 远程文件名
get 远程文件名 本地文件名
delete删除
这是当时已经成功实现功能的代码,具体的嘛,懒得讲了和说了,就是上传文件还有每进度5%给出日志提示
def vm_upload(**kwargs): step_progress_callback = kwargs.get('step_progress_callback') host = kwargs.get("IP") username = kwargs.get("LoginName") pwd = kwargs.get("LoginPwd") # 实例化 FTP ftp = FTP() # 设置调试等级, 0 不调试, 1 只打印命令与响应, 2 打印详细信息 ftp.set_debuglevel(0) # 设置 FTP 主动被动模式, False 主动模式, True 被动模式(默认的模式) ftp.set_pasv(True) # 设置编码格式 ftp.encoding = 'utf-8' try: # 连接与登录 ftp.connect(host, 21) ftp.login(username, pwd) logger.info(f"FTP connection successful: {ftp.getwelcome()}") step_progress_callback(20) # 切换到目标目录 ftp.cwd("/oas/images") logger.info("Switched to directory: /oas/images") # 检测是否已有虚拟机文件,有则跳过上传 remote_filename = VM_VMX local_file_to_upload = 'D:/'+VM_VMX try: # 尝试获取远程文件大小,如果文件存在则跳过上传 remote_file_size = ftp.size(remote_filename) logger.info(f"Remote file already exists, size: {remote_file_size} bytes. Skipping upload.") # 可选:比较文件大小,如果不同则覆盖上传 local_file_size = os.path.getsize(local_file_to_upload) if remote_file_size == local_file_size: logger.info("Local and remote file sizes match, skipping upload.") step_progress_callback(100) return True, "File already exists and sizes match, upload skipped" else: logger.info("File sizes differ, proceeding with upload...") # 删除远程文件以便重新上传 ftp.delete(remote_filename) logger.info("Deleted existing remote file for re-upload") except error_perm as e: # 文件不存在,继续上传 if "550" in str(e): logger.info("Remote file does not exist, proceeding with upload") else: raise e # 获取文件大小用于进度计算 file_size = os.path.getsize(local_file_to_upload) logger.info(f"Starting file upload, size: {file_size} bytes ({file_size / 1024 / 1024:.2f} MB)") # 进度跟踪变量 uploaded_size = 0 last_logged_progress = 0 def progress_callback(data): nonlocal uploaded_size, last_logged_progress uploaded_size += len(data) progress_percent = (uploaded_size / file_size) * 100 # 每完成5%记录一次日志,避免过于频繁的日志输出 if progress_percent - last_logged_progress >= 5 or uploaded_size == file_size: logger.info(f"Upload progress: {progress_percent:.1f}% ({uploaded_size}/{file_size} bytes)") last_logged_progress = progress_percent - (progress_percent % 5) # 更新步骤进度,从20%到100% step_progress = 20 + (progress_percent * 0.8) step_progress_callback(step_progress) # 上传文件(带进度回调) with open(local_file_to_upload, 'rb') as local_file: ftp.storbinary(f'STOR {remote_filename}', local_file, callback=progress_callback) logger.info("File upload completed") # 退出客户端 ftp.quit() step_progress_callback(100) return True, "upload vm successfully" except Exception as e: logger.error(f"File upload failed: {str(e)}") # 确保在异常情况下也关闭连接 try: if ftp: ftp.quit() except: pass return False, f"upload vm failed: {str(e)}"
浙公网安备 33010602011771号