CH395实现FTP_Client应用(上)
测试环境:CH30v307RCT6 + CH395Q,PC端工具:XLight (FTP服务器,语言为英文)
1.主要代码说明
(1)main.c
(2)CH395FTP.c
工程CH395FTP.c 99行 CH395_FTPInterCmd函数执行了四个主要的流程,包括登录、搜索目录、下载文件、上传文件。在该函数中可以修改想要访问的文件夹和文本文档名称,也可修改想要上传的文件夹及文本文档名称。(主要要和之后FTP服务器中的主目录设置保持一致)。
1 /******************************************************************************* 2 * Function Name : CH395_FTPInterCmd 3 * Description : 执行对应的命令,可自行调整执行顺序 4 * Input : NONE 5 * Output : None 6 * Return : None 7 *******************************************************************************/ 8 void CH395_FTPInterCmd( ) 9 { 10 switch(ftp.FileCmd){ 11 case FTP_CMD_LOGIN: /* 登陆 */ 12 if( CH395_FTPLogin( ) == FTP_COMMAND_SUCCESS ){ /* 登陆成功,可进行其他操作*/ 13 CH395_FTPSearch("USER","FILELIST.txt" ); /* 开始查询指定的目录下的文件*/ 14 printf("进入目录\r\n"); 15 } 16 break; 17 case FTP_CMD_SEARCH: /* 搜查文件(参数:目录名,文件名)*/ 18 if( CH395_FTPSearch("USER","FILELIST.txt" ) == FTP_COMMAND_SUCCESS ){ /* 查询命令执行完毕,可进行其他操作 */ 19 // printf("进入目录1\r\n"); 20 if( ftp.FindFile )CH395_FTPGetFile("FILELIST.txt" ); /* 搜查到指定的目录下的文件则开始下载文件 */ 21 else CH395_FTPQuit( ); /* 没搜查到指定的目录下的文件则退出(也可进行其他操作,如上传)*/ 22 } 23 break; 24 case FTP_CMD_GETFILE: /* 下载文件(参数:文件名)*/ 25 if(CH395_FTPGetFile("FILELIST.txt" ) == FTP_COMMAND_SUCCESS ){ /* 下载文件成功,可进行其他操作 */ 26 CH395_FTPPutFile("TEXT","abc.txt"); /* 上传文件 */ 27 } 28 break; 29 case FTP_CMD_PUTFILE: /* 上传文件(参数:目录名,文件名)*/ 30 if( CH395_FTPPutFile("TEXT","abc.txt")== FTP_COMMAND_SUCCESS ){ /* 上传文件成功,可进行其他操作*/ 31 CH395_FTPQuit( ); /* 退出 */ 32 } 33 break; 34 default: 35 break; 36 } 37 }
(3)CH395FTPCMD.c
该.c文件主要是对FTP协议相关命令码和应答的封装和处理。
下面一段代码是在工程CH395FTPCMD.c中的342行,要注意的点是有些FTP服务器使用的FTP协议版本不同或工具语言不同,会导致395对其发出的应答码解析错误。
例如:当Xlight语言选择中文时,发出的应答就是"200 类型....",这就和下面代码中的"200 Type'对不上了,就会导致解析错误以至于FTP传输卡住。
如果出现这种情况,建议打印一下recv_buff看一下具体的应答是否和代码一致,再做具体修改。
1 /******************************************************************************** 2 * Function Name : CH395_FTPCheckSearch 3 * Description : 验证搜查文件握手信号 4 * Input : recv_buff- 握手信息 5 check_type-检测的类型 6 * Output : None 7 * Return : None 8 *********************************************************************************/ 9 UINT8 CH395_FTPCheckSearch( char *recv_buff ) 10 { 11 printf("#####"); 12 13 if( strncmp("200 Type", recv_buff, 8) == 0 ){ /* 格式类型*/ 14 CH395_FTPDatServer( 1,&ftp.SouPort ); 15 CH395_FTPPort( ftp.SouPort ); 16 } 17 else if( strncmp("200 PORT", recv_buff, 8 ) == 0){ 18 CH395_FTPList( ); 19 } 20 else if( strncmp("150", recv_buff, 3) == 0 ){ /* 获取列表成功*/ 21 ftp.CmdDataS = FTP_MACH_RECEDATA; 22 } 23 else if( strncmp("226", recv_buff, 3) == 0 ){ /* 列表信息结束*/ 24 if(ftp.InterCmdS == FTP_MACH_FINDFILE) ftp.CmdStatus = FTP_MACH_SEARCHSUC; 25 if(ftp.FindList == 1){ 26 ftp.FindList = 0; 27 CH395_FTPCwd( 0 ); 28 } 29 ftp.InterCmdS = 0; 30 } 31 else if( strncmp("425", recv_buff, 3) == 0 ){ /* 无法建立数据连接*/ 32 CH395_FTPQuit( ); 33 } 34 else if( strncmp("250", recv_buff, 3) == 0 ){ /* 打开目录*/ 35 printf("250^^^^^^^^^^^^^^^^^^^^^^^^^^"); 36 ftp.InterCmdS = FTP_MACH_FINDFILE; 37 CH395_FTPType( ); 38 } 39 else if( strncmp("221", recv_buff, 3) == 0 ){ /* 退出登陆 */ 40 CH395CloseSocket( ftp.SocketCtl ); /* 关闭连接 */ 41 } 42 else return FTP_ERR_SEARCH; 43 return FTP_CHECK_SUCCESS; 44 }
(4)CH395FTPFILE.c
通过修改pTest中的内容,可以修改上传文档的内容。
1 const UINT8 *pTest = "abcdefghijklmnopqrstuvwxyz0123456789"; /* 上传文档的内容 */ 2 /********************************************************************************* 3 * Function Name : CH395_FTPFileRead 4 * Description : 传送数据 5 * Input : None 6 * Output : None 7 * Return : None 8 *********************************************************************************/ 9 void CH395_FTPFileRead( ) 10 { 11 memset( send_buff, '\0', sizeof(send_buff)); 12 if(strlen(pTest)<536) { 13 sprintf( send_buff, "%s\r\n",pTest); /*将数据写入发送缓冲区,如数据较大,分多次写入 */ 14 ftp.CmdDataS = FTP_MACH_DATAOVER; /*如果数据读完则置为数据读完标志位 */ 15 } 16 }
2.例程演示
(1)在PC机上创建一个名为USER的文件夹,然后在里面再创建一个名为USER的文件夹,在USER文件夹中创建 FILELIST.txt 。打开这个文本文档,在里面随便写一些内容。(文件的名称和代码中一致)
(2)下载XLight后(注意语言版本,选择英文版),点击,选择和395连接的网卡的IP,端口选择21,协议选择FTP,点击确定。
(3)双击所创建的FTP服务器,选择左侧列表中的Public Patch,点击右侧的"+",将Permission下的权限都勾选上,然后点击Browse选择目录,即选择第一步所创建的文件夹,注意选择到第一个USER(如图)。最后点击下面的确定。
(4)选中所创建的FTP服务器,点击上方的,之后再点击,创建用户名和登录密码(注意和代码保持一致),之后点击Browse选择主目录(和上一步一样),最后点击,将其中的权限都勾选上。
(5)烧录代码运行后,能看到成功通过FTP协议读取到了FILELIST.txt文本文档中的内容,并且成功在USER文件夹下创建了一个TEXT文件夹,里面有名为abc.txt的文本文档,其中的内容即代码所设置的需要上传的内容。
关于整个下载和上传的例程流程抓包和打印的解析可以看这篇博客,可在链接中下载对应代码和日志。
CH395实现FTP_Client应用(下) - lqlq123 - 博客园 (cnblogs.com)
参考例程:https://files.cnblogs.com/files/blogs/808422/CH395_FTP.zip?t=1710226512&download=true
抓包及log打印:https://files.cnblogs.com/files/blogs/808422/FTP_client_%E6%8A%93%E5%8C%85%E5%8F%8Alog%E6%89%93%E5%8D%B0.zip?t=1710226723&download=true