STM32+LWIP+FTP客户端下载文件

发布时间:2024-08-13  

前提


在学习FTP客户端之前需要学会socket,FTP客户端与服务器之间的通讯就是使用socket的过程。

思路:


整个过程需要两个socket,一个用于与服务器端之间的操作,比如输入账号密码、读取文件大小或者删除文件之类的操作,另外一个socket用于接收文件内容、一个流;具体流程看下面的流程图。


流程图:

FTP命令:

命令 描述
ABOR 中断数据连接程序
ACCT 系统特权帐号
ALLO 为服务器上的文件存储器分配字节
APPE 添加文件到服务器同名文件
CDUP 改变服务器上的父目录
CWD 改变服务器上的工作目录
DELE 删除服务器上的指定文件
HELP 返回指定命令信息
LIST 如果是文件名列出文件信息,如果是目录则列出文件列表
MODE 传输模式(S=流模式,B=块模式,C=压缩模式)
MKD 在服务器上建立指定目录
NLST 列出指定目录内容
NOOP 无动作,除了来自服务器上的承认
PASS 系统登录密码
PASV 请求服务器等待数据连接
PORT IP 地址和两字节的端口 ID
PWD 显示当前工作目录
QUIT 从 FTP 服务器上退出登录
REIN 重新初始化登录状态连接
REST 由特定偏移量重启文件传递
RETR 从服务器上找回(复制)文件
RMD 在服务器上删除指定目录
RNFR 对旧路径重命名
RNTO 对新路径重命名
SITE 由服务器提供的站点特殊参数
SMNT 挂载指定文件结构
STAT 在当前程序或目录上返回信息
STOR 储存(复制)文件到服务器上
STOU 储存文件到服务器名称上
STRU 数据结构(F=文件,R=记录,P=页面)
SYST 返回服务器使用的操作系统
TYPE 数据类型(A=ASCII,E=EBCDIC,I=binary)
USER > 系统登录的用户名

FTP响应码:

响应代码 解释说明
110 新文件指示器上的重启标记
120 服务器准备就绪的时间(分钟数)
125 打开数据连接,开始传输
150 打开连接
200 成功
202 命令没有执行
211 系统状态回复
212 目录状态回复
213 文件状态回复
214 帮助信息回复
215 系统类型回复
220 服务就绪
221 退出网络
225 打开数据连接
226 结束数据连接
227 进入被动模式(IP 地址、ID 端口)
230 登录因特网
250 文件行为完成
257 路径名建立
331 要求密码
332 要求帐号
350 文件行为暂停
421 服务关闭
425 无法打开数据连接
426 结束连接
450 文件不可用
451 遇到本地错误
452 磁盘空间不足
500 无效命令
501 错误参数
502 命令没有执行
503 错误指令序列
504 无效命令参数
530 未登录网络
532 存储文件需要帐号
550 文件不可用
551 不知道的页类型
552 超过存储分配
553 文件名不允许

实际使用例子

int FTP_Updata_Check(tFTP_DATA *pFtpData_cmd, tFTP_DATA *pFtpData_data)

{

int sock_ftp_cmd, sock_ftp_data;

struct sockaddr_in ftp_cmd, ftp_data;

uint32_t version_num = 0;

memset(pFtpData_data, 0, sizeof(tFTP_DATA));

memset(pFtpData_cmd, 0, sizeof(tFTP_DATA));

        if ((sock_ftp_cmd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 

{

printf('FTP: Socket_cmd application failed. . .');

return -1;

}

ftp_cmd.sin_family = AF_INET;

ftp_cmd.sin_port = htons(FTP_PORT_IND);

ftp_cmd.sin_addr.s_addr = inet_addr(FTP_IP_ADDR);

USER_INFO(ePRINTF_LV2, 'FTP: Connect Server IP:%s:%d', FTP_IP_ADDR, FTP_PORT_IND);

if (connect(sock_ftp_cmd, (struct sockaddr *)&ftp_cmd, sizeof (ftp_cmd)) < 0)

{

printf('FTP: The server connection failed. . .');

closesocket(sock_ftp_cmd);

return -1;

}

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

sprintf(pFtpData_cmd->send_buf, 'USER %srn', FTP_USERNAME);

write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

sprintf( pFtpData_cmd->send_buf, 'PASS %srn', FTP_PASS);

write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

sprintf( pFtpData_cmd->send_buf, 'PASVrn');

write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

pFtpData_data->port = ftp_get_port(pFtpData_cmd->recevice_buf);

if ((sock_ftp_data = socket(AF_INET, SOCK_STREAM, 0)) < 0) 

{

printf('FTP: Socket_dat application failed. . .');

closesocket(sock_ftp_cmd);

return -1;

}

ftp_data.sin_family = AF_INET;

ftp_data.sin_port = htons(pFtpData_data->port);

ftp_data.sin_addr.s_addr = inet_addr(FTP_IP_ADDR);

if (connect(sock_ftp_data, (struct sockaddr *)&ftp_data, sizeof (ftp_data)) < 0)

{

printf('FTP: The server connection failed. . .');

closesocket(sock_ftp_data);

closesocket(sock_ftp_cmd);

return -1;

}

sprintf(pFtpData_cmd->send_buf, 'SIZE abc.textrn');

write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));

memset(pFtpData_cmd->recevice_buf, 0, sizeof(pFtpData_cmd->recevice_buf));

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

USER_INFO(ePRINTF_LV3, 'FTP: <<<<%s', pFtpData_cmd->recevice_buf);

if(strstr(pFtpData_cmd->recevice_buf, 'File not found'))

{

printf('FTP: There is no file. return');

closesocket(sock_ftp_data);

closesocket(sock_ftp_cmd);

return 0;

}

sprintf(pFtpData_cmd->send_buf, 'RETR abc.textrn');

write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));

memset(pFtpData_cmd->recevice_buf, 0, sizeof(pFtpData_cmd->recevice_buf));

read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);

if(strstr(pFtpData_cmd->recevice_buf, 'File not found'))

{

printf('FTP: There is no file. return');

closesocket(sock_ftp_data);

closesocket(sock_ftp_cmd);


return 0;

}

read(sock_ftp_data, pFtpData_data->recevice_buf, sizeof(pFtpData_data->recevice_buf) - 1);//读文件内容

closesocket(sock_ftp_data);

closesocket(sock_ftp_cmd);


return 1;

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    ,如下图。注意:本教程下载器配置是配置一遍,后续教程将不再重复。 第五步:配置STM32的PC15,也就是2号引脚为GPIO_Output,并且配置标签为Zsdz_LED。 第六步:选择......
    外部晶振 4、下载器 选择四线的SWD接口下载器。 5、打开FreeRTOS 这里可以看到STM32CubeMX只提供了一种RTOS就是FreeRTOS,并且提供的是CMSIS接口API,并没......
    制作一个STM32下载器的过程;本文介绍制作一个STM32下载器的过程。 原理图 STLINK-V2下载器电路原理图如下。 上图中,H5接口是固件下载口。H4接口是STLINK-V2下载口(实现下载......
    曝龙芯3A6000处理器将首次支持同步多线程; 据报道在Linux 6.5的最新补丁,龙芯方面确认,3A6000将支持SMT(同步多线程),每个物理核心拥有两个逻辑核心。 首先,支持同步多线程......
    Linux 补丁显示龙芯 3A6000 系列处理器将支持同步多线程 SMT 技术;龙芯中科此前透露,龙芯 3A6000 已流片回来,但仅经过初步测试,后续还有性能摸底、优化与产品化的过程,而且......
    进入主界面 4、选择对应的烧录文件 5、点击Program Device按钮进行烧写,电脑上有多个jlink下载器的,会提示选择 6、选择对应的下载器后,将开始烧写 7、烧写出错、烧写......
    编译、Keil5程序下载、DAPLINK U盘拖拽下载以及串口程序下载。本文以RY-STM32开发板为例,布局图如下所示,开发板自带下载器DAPLink,与计算机通过USB线连接即可。其他类型的开发板编译与下载......
    单片机能实现真正的多线程吗?;所谓多线程都是模拟的,本质都是单线程,因为cpu同一时刻只能执行一段代码。 模拟的多线程就是任务之间快速切换,看起来像同时执行的样子。 据说最近有多核的单片机,不过......
    家分享一下,以下四个问题重要程度依次降低,分别是: ① 调试选项问题(默认会造成下载器无法下载); ② 定时器设置占空比的函数找不到报错的问题; ③ 硬件iic的一个小bug(亲测oled可以......
    基于STM32的虚拟多线程(TI_BLE协议栈_ZStack协议栈);基于STM32的虚拟多线程,可以很好的用于裸机程序中,用于模拟小型操作系统的多线程概念。本实例参考了参考TI_BLE协议......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>