--[[ @module ftp_up_download @summary ftp服务器上传下载文件处理应用功能模块 @version 001.000.000 @date 2025.07.29 @author 马亚丹 @usage 本文件为ftp服务器上传下载文件处理主应用功能模块,核心业务逻辑为: 1. 配置FTP客户端登录服务器的参数和文件路径 2. 封装一个重试机制,在登录失败、上传文件失败或者下载文件失败时尝试重新执行操作 3. 登录FTP服务器,通过重试机制确保登录成功 4. ftp.push上传本地文件到服务器,在本地新建文件并写入内容后上传到服务器指定路径,通过重试机制确保上传成功 5. ftp.pull从服务器下载文件,保存在本地指定路径,并读取文件长度,当长度小于指定字节时,读取文件内容,通常是设定512字节,如果文件太大,会消耗ram,通过重试机制确保上传成功 6. 主函数循环运行以下流程:登录服务器、用 ftp.command 操作 ftp 服务器目录以及文件上传下载处理后关闭服务器。 测试服务器为: 非ssl加密: local server_ip = "121.43.224.154" -- 服务器IP local server_port = 21 -- 服务器端口号 local server_username = "ftp_user" -- 服务器登陆用户名 local server_password = "3QujbiMG" -- 服务器登陆密码 本文件没有对外接口,直接在main.lua中require "ftp_up_download"就可以加载运行 ]] --1. 统一配置FTP参数和文件路径 local config = { server = { ip = "121.43.224.154", -- FTP服务器IP port = 21, -- FTP端口 username = "ftp_user", -- 登陆用户名 password = "3QujbiMG", -- 登陆密码 is_ssl = false, -- 若需SSL,补充证书 }, download = { remote_file = "/12222.txt", -- 服务器上要下载的文件 local_file = "/ftp_download.txt" -- 本地保存的文件名 }, upload = { local_file = "/ftp_upload.txt", -- 本地要上传的文件(会自动创建) remote_file = "/uploaded_by_luatos.txt" -- 服务器保存的文件名 } } --2.定义功能函数: 重试机制封装,针对易失败操作 local function retry_operation(operation, max_retries, interval) local retries = 0 while retries < max_retries do local result = operation() if result then return true end retries = retries + 1 log.warn("操作失败,重试第", retries, "次") sys.wait(interval) end log.error("超过最大重试次数") return false end --3.定义功能函数: 登录FTP服务器(带重试) local function ftp_login() --查看网卡适配器的联网状态是否IP_READY,true表示已经准备好可以联网了,false暂时不可以联网 while not socket.adapter(socket.dft()) do log.warn("ftp_login", "wait IP_READY", socket.dft()) -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY" -- 或者等待1秒超时退出阻塞等待状态; -- 注意:此处的1000毫秒超时不要修改的更长; -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡 -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配 -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft()) sys.waitUntil("IP_READY", 1000) end -- 检测到了IP_READY消息,设置默认网络适配器编号 log.info("ftp_login", "recv IP_READY", socket.dft()) --登录FTP服务器核心函数 local function ftp_login_result() local login_result = ftp.login( nil, config.server.ip, config.server.port, config.server.username, config.server.password, config.server.is_ssl ).wait() if login_result then log.info("FTP登录成功") return true end log.error("FTP登录失败") return false end -- 如果登录失败,最多重试登录3次,间隔3秒,可按需修改 return retry_operation(ftp_login_result, 3, 3000) end --4.定义功能函数: 上传文件到服务器(带重试) local function ftp_upload_file() -- 确保本地文件创建成功 -- 要写入文件的内容,按需求修改 local upload_content = "Luatos FTP上传测试数据 " local file, err = io.open(config.upload.local_file, "w") if not file then log.error("创建本地文件失败:", err) return false end --写入内容到文件 file:write(upload_content) file:close() --打印创建文件的结果 log.info("本地文件" .. config.upload.local_file .. "创建成功," .. "并写入文件内容:", upload_content) -- 上传文件核心函数 local function ftp_upload_result() log.info("开始上传文件:" .. config.upload.local_file) -- ftp.push参数:本地文件路径 → 服务器文件路径 local upload_ok = ftp.push( config.upload.local_file, config.upload.remote_file ).wait() if upload_ok then log.info("本地文件上传成功,保存在服务器路径:", config.upload.remote_file) return true end log.error("文件上传失败") return false end -- 如果上传失败,最多重试上传3次,间隔2秒,可按需修改 return retry_operation(ftp_upload_result, 3, 2000) end --5.定义功能函数: 下载文件到本地(带重试) local function ftp_download_file() local function ftp_download_result() log.info(" 开始下载文件:" .. config.download.remote_file) -- ftp.pull参数: 本地文件路径→服务器文件路径 local download_ok = ftp.pull( config.download.local_file, config.download.remote_file ).wait() if not download_ok then log.error("文件下载失败") return false end --检查下载结果 local file = io.open(config.download.local_file, "r") if not file then log.error("下载文件本地打开失败!重新下载") return false end local fsize = io.fileSize(config.download.local_file) if not fsize then log.error("读取文件大小失败,重新下载") return false end log.info("服务器上文件" .. config.download.remote_file .. "下载成功,保存在本地路径:", config.download.local_file, "大小:", fsize, "字节") if fsize and fsize <= 512 then local content = file:read("*a") file:close() log.info("下载文件内容长度小于512字节,内容是:", content) return true end -- 执行完操作后,一定要关掉文件 file:close() end -- 如果下载失败,最多重试10次,间隔2秒,可按需修改 return retry_operation(ftp_download_result, 10, 2000) end --6.定义功能函数: 功能测试主函数 local function ftp_main_task() while true do -- 步骤1:登录FTP服务器 if not ftp_login() then log.error("登录失败,退出流程") --退出前关闭连接,释放资源 ftp.close().wait() return end -- 执行FTP命令并检查结果 log.info("空操作,防止连接断掉", ftp.command("NOOP").wait()) log.info("报告远程系统的操作系统类型", ftp.command("SYST").wait()) log.info("指定文件类型", ftp.command("TYPE I").wait()) log.info("显示当前工作目录名", ftp.command("PWD").wait()) log.info("创建一个目录 目录名为QWER", ftp.command("MKD QWER").wait()) log.info("改变当前工作目录为QWER", ftp.command("CWD /QWER").wait()) log.info("返回上一层目录", ftp.command("CDUP").wait()) log.info("获取当前工作目录下的文件名列表", ftp.command("LIST").wait()) -- 步骤2:上传文件 if not ftp_upload_file() then log.error("上传失败,继续执行下载") -- 不中断流程 end -- 步骤3:下载文件 if not ftp_download_file() then log.error("下载失败") end -- 步骤4:清理操作(可选),清理之前创建的目录 log.info("删除测试目录QWER", ftp.command("RMD QWER").wait()) -- 步骤5:关闭连接 local close_result = ftp.close().wait() log.info("FTP连接关闭结果:", close_result) --步骤6:获取内存信息 local meminfo_result = rtos.meminfo("sys") log.info("meminfo内存信息", rtos.meminfo("sys")) --循环执行,每1分钟执行一次 sys.wait(1 * 60 * 1000) end end -- 启动主任务 sys.taskInit(ftp_main_task)