| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- --[[
- @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)
|