整理规范内容
This commit is contained in:
parent
d0cfee571c
commit
91915c8a9d
|
@ -0,0 +1,132 @@
|
||||||
|
# ##modbus-tcp##
|
||||||
|
|
||||||
|
## 1. 简介
|
||||||
|
|
||||||
|
基于XiZi内核一直FTP Client库,实现基于FTP协议的Client文件下载功能。
|
||||||
|
|
||||||
|
## 2. 数据结构设计说明
|
||||||
|
|
||||||
|
### 2.1 数据结构定义
|
||||||
|
```c
|
||||||
|
typedef struct ZftpClientStruct
|
||||||
|
{
|
||||||
|
char user_name[ZFTP_USER_NAME_LEN];
|
||||||
|
char password[ZFTP_PASSWORD_LEN];
|
||||||
|
char server_ip[ZFTP_SERVER_IP_LEN];
|
||||||
|
char data_port[6];
|
||||||
|
char control_port[6];
|
||||||
|
int control_socket;
|
||||||
|
int data_socket;
|
||||||
|
DownCallbackType download_write;
|
||||||
|
UpCallbackType upload_read;
|
||||||
|
void *user_data;
|
||||||
|
int errorno;
|
||||||
|
}ZftpClientType;
|
||||||
|
```
|
||||||
|
`ZftpClientType`结构体定义了一个FTP客户端的基本内容,包含服务器登陆的用户名、密码、服务器地址和端口号,以及处理数据上传和下载的回调函数指针。
|
||||||
|
|
||||||
|
### 2.2 FTP客户端下载流程与对应功能实现
|
||||||
|
#### 1. FTP客户端下载流程
|
||||||
|
ftp客户端从服务器下载文件基本流程如下:
|
||||||
|
从FTP服务器下载文件的基本流程如下:
|
||||||
|
1. 建立TCP连接,默认使用21端口。
|
||||||
|
2. 连接成功之后,服务器会发送一行欢迎文字,例如:220 welcome.
|
||||||
|
其中左边的数字220表示就绪状态,220后面有一个空格,空格后面是提示文字。
|
||||||
|
在解析命令应答的时候,只需要获取前面的数字即可。
|
||||||
|
3. 收到欢迎信息后,开始登陆,先用USER命令发送用户名,服务器返回331状态。
|
||||||
|
然后再用PASS命令发送登陆密码,服务器返回530表示密码错误,返回230表示密码正确。
|
||||||
|
发送:USER XXX
|
||||||
|
接收:331 Please, specify the password.
|
||||||
|
发送:PASS XXX
|
||||||
|
接收:230 Login successful.
|
||||||
|
4. 登陆成功之后,再发送一条TYPE I命令,进入二进制模式,这样获取文件数据的时候,就会以二进制字节流发送。避免以ASCII码格式发送文件数据。
|
||||||
|
5. 获取文件长度
|
||||||
|
发送:SIZE /path/filename
|
||||||
|
失败:550 /path/filename: No such file or directory
|
||||||
|
成功:213 [filesize]
|
||||||
|
返回[filesize]是十进制数字,表示该文件在大小,字节为单位
|
||||||
|
6. 下载文件
|
||||||
|
下载文件前,先发送PASV命令,进入被动模式,服务器开放一个新的端口,用于接收文件数据。
|
||||||
|
客户端连接数据端口后,发送RETR命令请求下载文件。
|
||||||
|
发送:PASV
|
||||||
|
接收:227 Entering Passive Mode (145,24,145,107,207,235).
|
||||||
|
发送:RETR /path/filename
|
||||||
|
接收:150 Opening BINARY mode data connection for /path/filename
|
||||||
|
从数据端口接收文件数据
|
||||||
|
接收:226 Transfer complete
|
||||||
|
#### 2. 功能实现说明
|
||||||
|
```c
|
||||||
|
/**
|
||||||
|
* @brief ftp客户端连接服务器
|
||||||
|
*
|
||||||
|
* @param user_name
|
||||||
|
* @param password
|
||||||
|
* @param server_ip
|
||||||
|
* @return ZftpClientType*
|
||||||
|
*/
|
||||||
|
ZftpClientType *ZFTPLogin(char *user_name, char *password, char *server_ip);
|
||||||
|
/**
|
||||||
|
* @brief 设置ftp上传下载功能回调函数
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @param dw_write
|
||||||
|
* @param up_read
|
||||||
|
* @param user_data
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPSetCallback(ZftpClientType *ftp, DownCallbackType dw_write, UpCallbackType up_read, void *user_data);
|
||||||
|
/**
|
||||||
|
* @brief 获取文件名的对应文件大小
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @param file_name
|
||||||
|
* @param file_size
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPGetFilesize(ZftpClientType *ftp, char *file_name, uint32_t *file_size);
|
||||||
|
/**
|
||||||
|
* @brief 切换服务器文件路径
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @param path
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPChangePath(ZftpClientType *ftp, char *path);
|
||||||
|
/**
|
||||||
|
* @brief 下载对应大小的文件
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @param file_name
|
||||||
|
* @param file_size
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPDownloadFile(ZftpClientType *ftp, char *file_name, int file_size);
|
||||||
|
/**
|
||||||
|
* @brief 退出服务器
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPQuit(ZftpClientType *ftp);
|
||||||
|
```
|
||||||
|
## 3. 测试程序说明
|
||||||
|
测试程序通过`TestFtpFileDownload`指令下载服务器中的10个文件名为1-10的4kb文本文件。
|
||||||
|
FTP服务器为FileZilla Server1.61。
|
||||||
|
|
||||||
|
## 4. 运行结果
|
||||||
|
1. 首先配置并编译代码。在配置选项中需要开启LWIP和SD-Card功能。
|
||||||
|
2. 设置本地FileZilla Server的服务器用户名和密码,服务器文件路径,并创建10个测试文件。
|
||||||
|
3. 通过`TestFtpFileDownload`执行文件下载功能测试。
|
||||||
|
1. 其中,FTP Server的结果如下:
|
||||||
|

|
||||||
|
可以看到,在成功连接FTPserver后,切换至服务器目录/,之后下载了文件名分别为1.txt~10.txt的10个个文件。每个文件大小均为4kb。
|
||||||
|
2. FTP Client的执行结果如下:
|
||||||
|

|
||||||
|
- 首先配置客户端IP和子网掩码等信息,之后进行了ftp登录并进入PASV模式。
|
||||||
|
- 接着对每个文件分别进行下载,知道文件内容全部下载完成。
|
||||||
|
|
||||||
|
3. 通过本地ls指令可以看到下载的文件大小为4096,与原文件大小一致
|
||||||
|

|
||||||
|
4. 通过cat指令查看文件内容,与原文件一致。
|
||||||
|

|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 125 KiB |
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
|
@ -1,27 +1,24 @@
|
||||||
/****************************************Copyright (c)****************************************************
|
/****************************************Copyright (c)****************************************************
|
||||||
** fhqlongteng@163.com
|
/*
|
||||||
** QQ:283669063
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
**--------------File Info---------------------------------------------------------------------------------
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
** File name: zFTP.c
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
** Last modified Date: 2020-12-01
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
** Last Version: V1.00
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
** Descriptions: ZFTP协议实现程序
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
**
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
** Created by: Zhao shimin
|
* See the Mulan PSL v2 for more details.
|
||||||
** Created date: 2020-12-01
|
*/
|
||||||
** Version: V1.00
|
|
||||||
** Descriptions:
|
/*
|
||||||
**
|
* @Description: 基于Lwip的Ftp协议实现
|
||||||
**
|
* @Version: V1.0.0
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* @Author: 好果汁有限公司
|
||||||
** Modified by:
|
* @Date: 2023-09-24 03:59:45
|
||||||
** Modified date:
|
* @LastEditors: blackcat 18436010132@163.com
|
||||||
** Version:
|
* @LastEditTime: 2023-09-30 16:53:39
|
||||||
** Descriptions:
|
*/
|
||||||
**
|
|
||||||
** Rechecked by:
|
|
||||||
*********************************************************************************************************/
|
|
||||||
|
|
||||||
#include "libftp.h"
|
#include "libftp.h"
|
||||||
|
|
||||||
|
@ -30,6 +27,7 @@
|
||||||
#include <lwip/sockets.h>
|
#include <lwip/sockets.h>
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
#include <lwip/netdb.h>
|
#include <lwip/netdb.h>
|
||||||
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ADD_NUTTX_FEATURES
|
#ifdef ADD_NUTTX_FEATURES
|
||||||
|
@ -37,18 +35,20 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_wait_server_ack()
|
* @brief 等待服务器响应
|
||||||
** Descriptions: FTP client wait server ack
|
*
|
||||||
** input parameters: socket, ack_code, wait_time
|
* @param socket
|
||||||
** output parameters: None
|
* @param ack_code
|
||||||
** Returned value: EOK, -ERROR
|
* @param wait_time
|
||||||
*********************************************************************************************************/
|
* @return EOK ERROR
|
||||||
static int zFTP_wait_server_ack(int socket, uint32_t *ack_code, uint32_t wait_time)
|
*/
|
||||||
|
static int ZFTPWaitServerAck(int socket, uint32_t *ack_code, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
fd_set readset;
|
fd_set readset;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
@ -60,7 +60,6 @@ static int zFTP_wait_server_ack(int socket, uint32_t *ack_code, uint32_t wait_t
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
/*wait the ack*/
|
/*wait the ack*/
|
||||||
|
|
||||||
FD_ZERO(&readset);
|
FD_ZERO(&readset);
|
||||||
FD_SET(socket, &readset);
|
FD_SET(socket, &readset);
|
||||||
|
|
||||||
|
@ -79,8 +78,6 @@ static int zFTP_wait_server_ack(int socket, uint32_t *ack_code, uint32_t wait_t
|
||||||
return -ERROR;
|
return -ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(1 == sscanf(ftp_recv_buf, "%d", &code))
|
if(1 == sscanf(ftp_recv_buf, "%d", &code))
|
||||||
{
|
{
|
||||||
*ack_code = code;
|
*ack_code = code;
|
||||||
|
@ -94,14 +91,18 @@ static int zFTP_wait_server_ack(int socket, uint32_t *ack_code, uint32_t wait_t
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_send_cmd_wait_server_ack()
|
/**
|
||||||
** Descriptions: FTP client send the command and wait the sever ack
|
* @brief 发送命令并等待响应
|
||||||
** input parameters: socket, cmd, cmd_len, ack_code, wait_time
|
*
|
||||||
** output parameters: None
|
* @param socket
|
||||||
** Returned value: EOK, -ERROR
|
* @param cmd
|
||||||
*********************************************************************************************************/
|
* @param cmd_len
|
||||||
static int zFTP_send_cmd_wait_server_ack(int socket, char *cmd, uint32_t cmd_len,
|
* @param ack_code
|
||||||
|
* @param wait_time
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
static int ZFTPSendComandWaitServerAck(int socket, char *cmd, uint32_t cmd_len,
|
||||||
uint32_t *ack_code, uint32_t wait_time)
|
uint32_t *ack_code, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
fd_set readset;
|
fd_set readset;
|
||||||
|
@ -156,14 +157,19 @@ static int zFTP_send_cmd_wait_server_ack(int socket, char *cmd, uint32_t cmd_len
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_filesize_send_cmd()
|
/**
|
||||||
** Descriptions: zFTP send the get filesize command
|
* @brief 获取文件大小
|
||||||
** input parameters: 无
|
*
|
||||||
** output parameters: 无
|
* @param socket
|
||||||
** Returned value: 无
|
* @param cmd
|
||||||
*********************************************************************************************************/
|
* @param cmd_len
|
||||||
static int zFTP_filesize_send_cmd(int socket, char *cmd, uint32_t cmd_len, uint32_t *ack_code,
|
* @param ack_code
|
||||||
|
* @param file_size
|
||||||
|
* @param wait_time
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
static int ZFTPFilesizeSendCmd(int socket, char *cmd, uint32_t cmd_len, uint32_t *ack_code,
|
||||||
uint32_t *file_size, uint32_t wait_time)
|
uint32_t *file_size, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
fd_set readset;
|
fd_set readset;
|
||||||
|
@ -220,18 +226,19 @@ static int zFTP_filesize_send_cmd(int socket, char *cmd, uint32_t cmd_len, uint3
|
||||||
return -ERROR;
|
return -ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: ftp_pasv_mode()
|
* @brief FTP客户端发送命令给服务器进入pasv模式
|
||||||
** Descriptions: FTP客户端发送命令给服务器进入pasv模式
|
*
|
||||||
** input parameters: 无
|
* @param socket
|
||||||
** output parameters: 无
|
* @param ack_code
|
||||||
** Returned value: 无
|
* @param server_port
|
||||||
*********************************************************************************************************/
|
* @param wait_time
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
static int zFTP_pasv_mode(int socket,uint32_t *ack_code, uint16_t *server_port, uint32_t wait_time)
|
static int zFTP_pasv_mode(int socket,uint32_t *ack_code, uint16_t *server_port, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
fd_set readset;
|
fd_set readset;
|
||||||
|
@ -292,90 +299,17 @@ static int zFTP_pasv_mode(int socket,uint32_t *ack_code, uint16_t *server_port,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_upload_file_data()
|
* @brief 下载文件数据
|
||||||
** Descriptions: zFTP download the file data
|
*
|
||||||
** input parameters: socket, buf, buf_size, wait_time
|
* @param socket
|
||||||
** output parameters: rd_len
|
* @param buf
|
||||||
** Returned value: EOK, -ERROR
|
* @param buf_size
|
||||||
*********************************************************************************************************/
|
* @param rd_len
|
||||||
static int zFTP_upload_file_data(zftp_client *ftp, char *file_name, uint32_t wait_time)
|
* @param wait_time
|
||||||
{
|
* @return int
|
||||||
struct timeval timeout;
|
*/
|
||||||
fd_set writeset;
|
static int ZFTPDownloadFileData(int socket, uint8_t *buf, uint32_t buf_size,
|
||||||
int socket= -1;
|
|
||||||
uint8_t *file_buf = NULL;
|
|
||||||
uint32_t rd_len = 0, file_pos= 0, total_len = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
timeout.tv_sec = wait_time/1000;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
|
|
||||||
|
|
||||||
socket = ftp->data_socket;
|
|
||||||
|
|
||||||
file_buf = malloc(ZFTP_FILE_DATA_BUF_SIZE);
|
|
||||||
if(file_buf == NULL)
|
|
||||||
{
|
|
||||||
printf("Cannot malloc the file data buf!");
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ftp->upload_read == NULL)
|
|
||||||
{
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(EOK != ftp->upload_read(ftp, file_name, file_buf, ZFTP_FILE_DATA_BUF_SIZE, file_pos, &rd_len, &total_len))
|
|
||||||
{
|
|
||||||
free(file_buf);
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
FD_ZERO(&writeset);
|
|
||||||
FD_SET(socket, &writeset);
|
|
||||||
if (select(socket + 1, NULL, &writeset, NULL, &timeout) <= 0)
|
|
||||||
{
|
|
||||||
free(file_buf);
|
|
||||||
printf("select data write socket timeout!");
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait and receive the packet back from the server. If n == -1, it failed.
|
|
||||||
if(rd_len != send(socket, (char*)file_buf, rd_len, 0))
|
|
||||||
{
|
|
||||||
free(file_buf);
|
|
||||||
printf("reading data socket error!");
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_pos = file_pos + rd_len;
|
|
||||||
|
|
||||||
if(file_pos >= total_len)
|
|
||||||
{
|
|
||||||
/*upload the file finish!*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
free(file_buf);
|
|
||||||
return EOK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_download_file_data()
|
|
||||||
** Descriptions: zFTP download the file data
|
|
||||||
** input parameters: socket, buf, buf_size, wait_time
|
|
||||||
** output parameters: rd_len
|
|
||||||
** Returned value: EOK, -ERROR
|
|
||||||
*********************************************************************************************************/
|
|
||||||
static int zFTP_download_file_data(int socket, uint8_t *buf, uint32_t buf_size,
|
|
||||||
uint32_t *rd_len, uint32_t wait_time)
|
uint32_t *rd_len, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
@ -412,14 +346,19 @@ static int zFTP_download_file_data(int socket, uint8_t *buf, uint32_t buf_size,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_download_send_cmd()
|
/**
|
||||||
** Descriptions: zFTP send the download file command
|
* @brief 请求下载文件
|
||||||
** input parameters: 无
|
*
|
||||||
** output parameters: 无
|
* @param socket
|
||||||
** Returned value: 无
|
* @param cmd
|
||||||
*********************************************************************************************************/
|
* @param cmd_len
|
||||||
static int zFTP_download_send_cmd(int socket, char *cmd, uint32_t cmd_len, uint32_t *ack_code,
|
* @param ack_code
|
||||||
|
* @param file_size
|
||||||
|
* @param wait_time
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
static int ZFTPDownloadSendCmd(int socket, char *cmd, uint32_t cmd_len, uint32_t *ack_code,
|
||||||
uint32_t *file_size, uint32_t wait_time)
|
uint32_t *file_size, uint32_t wait_time)
|
||||||
{
|
{
|
||||||
fd_set readset;
|
fd_set readset;
|
||||||
|
@ -463,17 +402,10 @@ static int zFTP_download_send_cmd(int socket, char *cmd, uint32_t cmd_len, uint3
|
||||||
return -ERROR;
|
return -ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*获取文件大小和应答码*/
|
/*获取应答码*/
|
||||||
// if(2 == sscanf(ftp_recv_buf, "%d%*[^(](%d", &code,&a))
|
|
||||||
// {
|
|
||||||
// *ack_code = code;
|
|
||||||
// *file_size = a;
|
|
||||||
// return EOK;
|
|
||||||
// }
|
|
||||||
if(1 == sscanf(ftp_recv_buf, "%d%*[^(](", &code))
|
if(1 == sscanf(ftp_recv_buf, "%d%*[^(](", &code))
|
||||||
{
|
{
|
||||||
*ack_code = code;
|
*ack_code = code;
|
||||||
// *file_size = a; //通过ftp zilla抓包分析,response中不含size
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -481,28 +413,25 @@ static int zFTP_download_send_cmd(int socket, char *cmd, uint32_t cmd_len, uint3
|
||||||
printf("Rcv data:%s\n", ftp_recv_buf);
|
printf("Rcv data:%s\n", ftp_recv_buf);
|
||||||
return -ERROR;
|
return -ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_quit()
|
* @brief 退出服务器并释放客户端资源
|
||||||
** Descriptions: ftp logout and realse the zftp_client
|
*
|
||||||
** input parameters: ftp
|
* @param ftp
|
||||||
** output parameters: None
|
* @return int
|
||||||
** Returned value: EOK
|
*/
|
||||||
*********************************************************************************************************/
|
int ZFTPQuit(ZftpClientType *ftp)
|
||||||
int zFTP_quit(zftp_client *ftp)
|
|
||||||
{
|
{
|
||||||
uint32_t ack_code = 0;
|
uint32_t ack_code = 0;
|
||||||
char cmd_buf[50] = {0};
|
char cmd_buf[50] = {0};
|
||||||
|
|
||||||
//ASSERT(ftp);
|
assert(ftp);
|
||||||
|
|
||||||
/*退出登陆*/
|
/*退出登陆*/
|
||||||
strcpy(cmd_buf, "QUIT\r\n");
|
strcpy(cmd_buf, "QUIT\r\n");
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPSendComandWaitServerAck(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 221))
|
(ack_code != 221))
|
||||||
{
|
{
|
||||||
printf("Server logout error, ack_code:%d", ack_code);
|
printf("Server logout error, ack_code:%d", ack_code);
|
||||||
|
@ -518,132 +447,16 @@ int zFTP_quit(zftp_client *ftp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_upload_file()
|
|
||||||
** Descriptions: upload the file to FTP server
|
|
||||||
** input parameters: ftp, path, file_name
|
|
||||||
** output parameters: file_size
|
|
||||||
** Returned value: zftp_client
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int zFTP_upload_file(zftp_client *ftp, char *file_name)
|
|
||||||
{
|
|
||||||
char cmd_buf[50] = {0};
|
|
||||||
uint32_t ack_code = 0;
|
|
||||||
int ret = EOK, fd = 0;
|
|
||||||
struct addrinfo hints, *addr_list = NULL, *cur = NULL;
|
|
||||||
uint16_t port = 0;
|
|
||||||
|
|
||||||
//ASSERT(ftp);
|
|
||||||
|
|
||||||
|
/**
|
||||||
/*Enter the pasv mode */
|
* @brief 从服务器下载文件
|
||||||
if(EOK != zFTP_pasv_mode(ftp->control_socket, &ack_code, &port, ZFTP_CMD_TIMEOUT) || (ack_code != 227))
|
*
|
||||||
{
|
* @param ftp
|
||||||
printf("Enter pasv mode error, ack_code:%d", ack_code);
|
* @param file_name
|
||||||
ret = -ERROR;
|
* @param _file_size
|
||||||
goto __exit;
|
* @return int
|
||||||
}
|
*/
|
||||||
|
int ZFTPDownloadFile(ZftpClientType *ftp, char *file_name, int _file_size)
|
||||||
|
|
||||||
/*creat the data socket link */
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
|
||||||
|
|
||||||
sprintf(ftp->data_port, "%d", port);
|
|
||||||
|
|
||||||
/* Do name resolution with both IPv6 and IPv4 */
|
|
||||||
if (getaddrinfo(ftp->server_ip, ftp->data_port, &hints, &addr_list) != EOK)
|
|
||||||
{
|
|
||||||
goto __exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cur = addr_list; cur != NULL; cur = cur->ai_next)
|
|
||||||
{
|
|
||||||
fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0)
|
|
||||||
{
|
|
||||||
ftp->data_socket = fd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
closesocket(fd);
|
|
||||||
|
|
||||||
}
|
|
||||||
freeaddrinfo(addr_list);
|
|
||||||
|
|
||||||
if(ftp->data_socket < 0)
|
|
||||||
{
|
|
||||||
ret = -ERROR;
|
|
||||||
goto __exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*send download the file command*/
|
|
||||||
sprintf(cmd_buf, "STOR %s\r\n", file_name);
|
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
|
||||||
(ack_code != 150))
|
|
||||||
{
|
|
||||||
printf("upload file error, ack_code:%d", ack_code);
|
|
||||||
ret = -ERROR;
|
|
||||||
goto __exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* read the file send to FTP server */
|
|
||||||
if(EOK == zFTP_upload_file_data(ftp, file_name, ZFTP_CMD_TIMEOUT))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = -ERROR;
|
|
||||||
goto __exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*close the data socket*/
|
|
||||||
if(ftp->data_socket >= 0)
|
|
||||||
{
|
|
||||||
closesocket(ftp->data_socket);
|
|
||||||
ftp->data_socket = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*waite the upload file finish */
|
|
||||||
if((EOK != zFTP_wait_server_ack(ftp->control_socket, &ack_code, ZFTP_CMD_TIMEOUT)) || (ack_code != 226))
|
|
||||||
{
|
|
||||||
printf("Server not ack download complete, ack_code:%d", ack_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = EOK;
|
|
||||||
|
|
||||||
__exit:
|
|
||||||
if(ftp->data_socket >= 0)
|
|
||||||
{
|
|
||||||
closesocket(ftp->data_socket);
|
|
||||||
ftp->data_socket = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_download_file()
|
|
||||||
** Descriptions: download the file from FTP server
|
|
||||||
** input parameters: ftp, path, file_name
|
|
||||||
** output parameters: file_size
|
|
||||||
** Returned value: zftp_client
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int zFTP_download_file(zftp_client *ftp, char *file_name, int _file_size)
|
|
||||||
{
|
{
|
||||||
char cmd_buf[50] = {0};
|
char cmd_buf[50] = {0};
|
||||||
uint32_t ack_code = 0;
|
uint32_t ack_code = 0;
|
||||||
|
@ -655,7 +468,7 @@ int zFTP_download_file(zftp_client *ftp, char *file_name, int _file_size)
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
uint32_t file_size = _file_size;
|
uint32_t file_size = _file_size;
|
||||||
|
|
||||||
//ASSERT(ftp);
|
assert(ftp);
|
||||||
|
|
||||||
file_buf = malloc(ZFTP_FILE_DATA_BUF_SIZE);
|
file_buf = malloc(ZFTP_FILE_DATA_BUF_SIZE);
|
||||||
if(file_buf == NULL)
|
if(file_buf == NULL)
|
||||||
|
@ -715,7 +528,7 @@ int zFTP_download_file(zftp_client *ftp, char *file_name, int _file_size)
|
||||||
|
|
||||||
/*send download the file command*/
|
/*send download the file command*/
|
||||||
sprintf(cmd_buf, "RETR %s\r\n", file_name);
|
sprintf(cmd_buf, "RETR %s\r\n", file_name);
|
||||||
if((EOK != zFTP_download_send_cmd(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, &file_size, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPDownloadSendCmd(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, &file_size, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 150))
|
(ack_code != 150))
|
||||||
{
|
{
|
||||||
printf("Download file error, ack_code:%d\n", ack_code);
|
printf("Download file error, ack_code:%d\n", ack_code);
|
||||||
|
@ -727,7 +540,7 @@ int zFTP_download_file(zftp_client *ftp, char *file_name, int _file_size)
|
||||||
/* read the file */
|
/* read the file */
|
||||||
while(file_size > file_pos)
|
while(file_size > file_pos)
|
||||||
{
|
{
|
||||||
if(EOK == zFTP_download_file_data(ftp->data_socket, file_buf, ZFTP_FILE_DATA_BUF_SIZE, &rd_len, ZFTP_CMD_TIMEOUT))
|
if(EOK == ZFTPDownloadFileData(ftp->data_socket, file_buf, ZFTP_FILE_DATA_BUF_SIZE, &rd_len, ZFTP_CMD_TIMEOUT))
|
||||||
{
|
{
|
||||||
if((rd_len) && (ftp->download_write))
|
if((rd_len) && (ftp->download_write))
|
||||||
{
|
{
|
||||||
|
@ -748,7 +561,7 @@ int zFTP_download_file(zftp_client *ftp, char *file_name, int _file_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*waite the download file finish */
|
/*waite the download file finish */
|
||||||
if((EOK != zFTP_wait_server_ack(ftp->control_socket, &ack_code, ZFTP_CMD_TIMEOUT)) || (ack_code != 226) || (file_pos !=file_size ))
|
if((EOK != ZFTPWaitServerAck(ftp->control_socket, &ack_code, ZFTP_CMD_TIMEOUT)) || (ack_code != 226) || (file_pos !=file_size ))
|
||||||
{
|
{
|
||||||
printf("Server not ack download complete, ack_code:%d\n", ack_code);
|
printf("Server not ack download complete, ack_code:%d\n", ack_code);
|
||||||
ret = ERROR;
|
ret = ERROR;
|
||||||
|
@ -778,25 +591,23 @@ __exit:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_change_path()
|
* @brief 切换服务器路径
|
||||||
** Descriptions: change the path of FTP server
|
*
|
||||||
** input parameters: ftp, path, path
|
* @param ftp
|
||||||
** output parameters: file_size
|
* @param path
|
||||||
** Returned value: zftp_client
|
* @return int
|
||||||
*********************************************************************************************************/
|
*/
|
||||||
int zFTP_change_path(zftp_client *ftp, char *path)
|
int ZFTPChangePath(ZftpClientType *ftp, char *path)
|
||||||
{
|
{
|
||||||
char cmd_buf[50] = {0};
|
char cmd_buf[50] = {0};
|
||||||
uint32_t ack_code = 0;
|
uint32_t ack_code = 0;
|
||||||
|
|
||||||
//ASSERT(ftp);
|
assert(ftp);
|
||||||
//ASSERT(path);
|
assert(path);
|
||||||
|
|
||||||
/*change path*/
|
/*change path*/
|
||||||
|
|
||||||
sprintf(cmd_buf, "CWD %s\r\n", path);
|
sprintf(cmd_buf, "CWD %s\r\n", path);
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPSendComandWaitServerAck(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 250))
|
(ack_code != 250))
|
||||||
{
|
{
|
||||||
printf("Switch dir error, ack_code:%d", ack_code);
|
printf("Switch dir error, ack_code:%d", ack_code);
|
||||||
|
@ -811,26 +622,24 @@ int zFTP_change_path(zftp_client *ftp, char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
/*********************************************************************************************************
|
* @brief 获取文件大小
|
||||||
** Function name: zFTP_get_filesize()
|
*
|
||||||
** Descriptions: get the file size from FTP server
|
* @param ftp
|
||||||
** input parameters: ftp, path, file_name
|
* @param file_name
|
||||||
** output parameters: file_size
|
* @param file_size
|
||||||
** Returned value: zftp_client
|
* @return int
|
||||||
*********************************************************************************************************/
|
*/
|
||||||
int zFTP_get_filesize(zftp_client *ftp, char *file_name, uint32_t *file_size)
|
int ZFTPGetFilesize(ZftpClientType *ftp, char *file_name, uint32_t *file_size)
|
||||||
{
|
{
|
||||||
char cmd_buf[50] = {0};
|
char cmd_buf[50] = {0};
|
||||||
uint32_t ack_code = 0;
|
uint32_t ack_code = 0;
|
||||||
|
|
||||||
//ASSERT(ftp);
|
assert(ftp);
|
||||||
//ASSERT(file_name);
|
assert(file_name);
|
||||||
|
|
||||||
|
|
||||||
/*get the file size*/
|
/*get the file size*/
|
||||||
sprintf(cmd_buf, "SIZE %s\r\n", file_name);
|
sprintf(cmd_buf, "SIZE %s\r\n", file_name);
|
||||||
if((EOK != zFTP_filesize_send_cmd(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, file_size, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPFilesizeSendCmd(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, file_size, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 213))
|
(ack_code != 213))
|
||||||
{
|
{
|
||||||
printf("Get file size error, ack_code:%d", ack_code);
|
printf("Get file size error, ack_code:%d", ack_code);
|
||||||
|
@ -845,16 +654,19 @@ int zFTP_get_filesize(zftp_client *ftp, char *file_name, uint32_t *file_size)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_set_callback()
|
/**
|
||||||
** Descriptions: set the file download and upload callback function
|
* @brief 设置客户端上传与下载回调函数
|
||||||
** input parameters: ftp, dw_write, up_read, user_data
|
*
|
||||||
** output parameters: None
|
* @param ftp
|
||||||
** Returned value: EOK
|
* @param dw_write
|
||||||
*********************************************************************************************************/
|
* @param up_read
|
||||||
int zFTP_set_callback(zftp_client *ftp, down_callback dw_write, up_callback up_read, void *user_data)
|
* @param user_data
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPSetCallback(ZftpClientType *ftp, DownCallbackType dw_write, UpCallbackType up_read, void *user_data)
|
||||||
{
|
{
|
||||||
//ASSERT(ftp);
|
assert(ftp);
|
||||||
|
|
||||||
ftp->download_write = dw_write;
|
ftp->download_write = dw_write;
|
||||||
ftp->upload_read = up_read;
|
ftp->upload_read = up_read;
|
||||||
|
@ -864,16 +676,17 @@ int zFTP_set_callback(zftp_client *ftp, down_callback dw_write, up_callback up_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_login()
|
* @brief 客户端登录
|
||||||
** Descriptions: ftp login server
|
*
|
||||||
** input parameters: user_name, password, server_ip
|
* @param user_name
|
||||||
** output parameters: None
|
* @param password
|
||||||
** Returned value: zftp_client
|
* @param server_ip
|
||||||
*********************************************************************************************************/
|
* @return ZftpClientType*
|
||||||
zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
*/
|
||||||
|
ZftpClientType *ZFTPLogin(char *user_name, char *password, char *server_ip)
|
||||||
{
|
{
|
||||||
zftp_client *ftp = NULL;
|
ZftpClientType *ftp = NULL;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
uint32_t ack_code = 0;
|
uint32_t ack_code = 0;
|
||||||
char cmd_buf[50] = {0};
|
char cmd_buf[50] = {0};
|
||||||
|
@ -887,11 +700,11 @@ zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*create a zftp client buf*/
|
/*create a zftp client buf*/
|
||||||
ftp = malloc(sizeof(zftp_client));
|
ftp = malloc(sizeof(ZftpClientType));
|
||||||
|
|
||||||
if(ftp)
|
if(ftp)
|
||||||
{
|
{
|
||||||
memset(ftp, 0, sizeof(zftp_client));
|
memset(ftp, 0, sizeof(ZftpClientType));
|
||||||
|
|
||||||
ftp->data_socket = -1;
|
ftp->data_socket = -1;
|
||||||
ftp->control_socket = -1;
|
ftp->control_socket = -1;
|
||||||
|
@ -935,7 +748,7 @@ zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
||||||
if(ftp->control_socket >= 0)
|
if(ftp->control_socket >= 0)
|
||||||
{
|
{
|
||||||
/* wait the login success and welcome*/
|
/* wait the login success and welcome*/
|
||||||
if(EOK != zFTP_wait_server_ack(ftp->control_socket, &ack_code, ZFTP_CMD_TIMEOUT) || (ack_code != 220))
|
if(EOK != ZFTPWaitServerAck(ftp->control_socket, &ack_code, ZFTP_CMD_TIMEOUT) || (ack_code != 220))
|
||||||
{
|
{
|
||||||
printf("Server not ack welcome, ack_code:%d", ack_code);
|
printf("Server not ack welcome, ack_code:%d", ack_code);
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -943,7 +756,7 @@ zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
||||||
|
|
||||||
/*input the user name */
|
/*input the user name */
|
||||||
sprintf(cmd_buf, "USER %s\r\n", ftp->user_name);
|
sprintf(cmd_buf, "USER %s\r\n", ftp->user_name);
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPSendComandWaitServerAck(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 331))
|
(ack_code != 331))
|
||||||
{
|
{
|
||||||
printf("Login user error, ack_code:%d", ack_code);
|
printf("Login user error, ack_code:%d", ack_code);
|
||||||
|
@ -952,7 +765,7 @@ zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
||||||
|
|
||||||
/*input the password */
|
/*input the password */
|
||||||
sprintf(cmd_buf, "PASS %s\r\n", ftp->password);
|
sprintf(cmd_buf, "PASS %s\r\n", ftp->password);
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPSendComandWaitServerAck(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 230))
|
(ack_code != 230))
|
||||||
{
|
{
|
||||||
printf("Login password error, ack_code:%d", ack_code);
|
printf("Login password error, ack_code:%d", ack_code);
|
||||||
|
@ -961,7 +774,7 @@ zftp_client *zFTP_login(char *user_name, char *password, char *server_ip)
|
||||||
|
|
||||||
/*change bin mode*/
|
/*change bin mode*/
|
||||||
strcpy(cmd_buf, "TYPE I\r\n");
|
strcpy(cmd_buf, "TYPE I\r\n");
|
||||||
if((EOK != zFTP_send_cmd_wait_server_ack(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
if((EOK != ZFTPSendComandWaitServerAck(ftp->control_socket, cmd_buf, strlen(cmd_buf), &ack_code, ZFTP_CMD_TIMEOUT)) ||
|
||||||
(ack_code != 200))
|
(ack_code != 200))
|
||||||
{
|
{
|
||||||
printf("Switch bin mode error, ack_code:%d", ack_code);
|
printf("Switch bin mode error, ack_code:%d", ack_code);
|
||||||
|
@ -989,7 +802,5 @@ __exit:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*********************************************************************************************************
|
|
||||||
** End of file
|
|
||||||
*********************************************************************************************************/
|
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,30 @@
|
||||||
/****************************************Copyright (c)****************************************************
|
/*
|
||||||
** fhqlongteng@163.com
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
** QQ:283669063
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
**--------------File Info---------------------------------------------------------------------------------
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
** File name: zFTP.h
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
** Last modified Date: 2020-12-01
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
** Last Version: V1.00
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
** Descriptions: FTP通信协议头文件
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
**
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* See the Mulan PSL v2 for more details.
|
||||||
** Created by: Zhao shimin
|
*/
|
||||||
** Created date: 2020-12-01
|
|
||||||
** Version: V1.00
|
/*
|
||||||
** Descriptions:
|
* @Description: 基于Lwip的Ftp协议实现
|
||||||
**
|
* @Version: V1.0.0
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* @Author: 好果汁有限公司
|
||||||
** Modified by:
|
* @Date: 2023-09-24 03:59:45
|
||||||
** Modified date:
|
* @LastEditors: blackcat 18436010132@163.com
|
||||||
** Version:
|
* @LastEditTime: 2023-09-30 16:53:39
|
||||||
** Descriptions:
|
*/
|
||||||
**
|
|
||||||
** Rechecked by:
|
#ifndef __LIBFTP_H_
|
||||||
*********************************************************************************************************/
|
#define __LIBFTP_H_
|
||||||
#ifndef __zFTP_H_
|
|
||||||
#define __zFTP_H_
|
|
||||||
|
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
* 定义FTP的客户端的存储的缓冲区长度
|
|
||||||
*********************************************************************************************************/
|
|
||||||
#ifndef ZFTP_USER_NAME_LEN
|
#ifndef ZFTP_USER_NAME_LEN
|
||||||
#define ZFTP_USER_NAME_LEN 20
|
#define ZFTP_USER_NAME_LEN 20
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,89 +49,91 @@
|
||||||
#define ZFTP_CMD_TIMEOUT 2000
|
#define ZFTP_CMD_TIMEOUT 2000
|
||||||
|
|
||||||
|
|
||||||
typedef int (*down_callback)(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t total_len);
|
typedef int (*DownCallbackType)(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t total_len);
|
||||||
typedef int (*up_callback)(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t *read_len, uint32_t *total_len);
|
typedef int (*UpCallbackType)(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t *read_len, uint32_t *total_len);
|
||||||
/*********************************************************************************************************
|
|
||||||
* 定义zFTP通信管理数据结构
|
|
||||||
*********************************************************************************************************/
|
typedef struct ZftpClientStruct
|
||||||
typedef struct zftp_client_struct
|
|
||||||
{
|
{
|
||||||
char user_name[ZFTP_USER_NAME_LEN];
|
char user_name[ZFTP_USER_NAME_LEN];
|
||||||
char password[ZFTP_PASSWORD_LEN];
|
char password[ZFTP_PASSWORD_LEN];
|
||||||
char server_ip[ZFTP_SERVER_IP_LEN];
|
char server_ip[ZFTP_SERVER_IP_LEN];
|
||||||
char data_port[6];
|
char data_port[6];
|
||||||
char control_port[6];
|
char control_port[6];
|
||||||
int control_socket; /* FTP控制socket */
|
int control_socket; /* FTP control socket */
|
||||||
int data_socket; /* FTP数据socket */
|
int data_socket; /* FTP data socket */
|
||||||
down_callback download_write;
|
DownCallbackType download_write;
|
||||||
up_callback upload_read;
|
UpCallbackType upload_read;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
int errorno;
|
int errorno;
|
||||||
|
|
||||||
}zftp_client;
|
}ZftpClientType;
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_login()
|
|
||||||
** Descriptions: ftp login server
|
|
||||||
** input parameters: user_name, password, server_ip
|
|
||||||
** output parameters: None
|
|
||||||
** Returned value: zftp_client
|
|
||||||
*********************************************************************************************************/
|
|
||||||
zftp_client *zFTP_login(char *user_name, char *password, char *server_ip);
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_set_callback()
|
* @brief ftp客户端连接服务器
|
||||||
** Descriptions: set the file download and upload callback function
|
*
|
||||||
** input parameters: ftp, dw_write, up_read, user_data
|
* @param user_name
|
||||||
** output parameters: None
|
* @param password
|
||||||
** Returned value: RT_EOK
|
* @param server_ip
|
||||||
*********************************************************************************************************/
|
* @return ZftpClientType*
|
||||||
int zFTP_set_callback(zftp_client *ftp, down_callback dw_write, up_callback up_read, void *user_data);
|
*/
|
||||||
|
ZftpClientType *ZFTPLogin(char *user_name, char *password, char *server_ip);
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_get_filesize()
|
|
||||||
** Descriptions: get the file size from FTP server
|
|
||||||
** input parameters: ftp, path, file_name
|
|
||||||
** output parameters: file_size
|
|
||||||
** Returned value: zftp_client
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int zFTP_get_filesize(zftp_client *ftp, char *file_name, uint32_t *file_size);
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_change_path()
|
* @brief 设置ftp上传下载功能回调函数
|
||||||
** Descriptions: change the path of FTP server
|
*
|
||||||
** input parameters: ftp, path, path
|
* @param ftp
|
||||||
** output parameters: file_size
|
* @param dw_write
|
||||||
** Returned value: zftp_client
|
* @param up_read
|
||||||
*********************************************************************************************************/
|
* @param user_data
|
||||||
int zFTP_change_path(zftp_client *ftp, char *path);
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPSetCallback(ZftpClientType *ftp, DownCallbackType dw_write, UpCallbackType up_read, void *user_data);
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_download_file()
|
|
||||||
** Descriptions: download the file from FTP server
|
|
||||||
** input parameters: ftp, path, file_name
|
|
||||||
** output parameters: file_size
|
|
||||||
** Returned value: zftp_client
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int zFTP_download_file(zftp_client *ftp, char *file_name, int file_size);
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/**
|
||||||
** Function name: zFTP_upload_file()
|
* @brief 获取文件名的对应文件大小
|
||||||
** Descriptions: upload the file to FTP server
|
*
|
||||||
** input parameters: ftp, path, file_name
|
* @param ftp
|
||||||
** output parameters: file_size
|
* @param file_name
|
||||||
** Returned value: zftp_client
|
* @param file_size
|
||||||
*********************************************************************************************************/
|
* @return int
|
||||||
int zFTP_upload_file(zftp_client *ftp, char *file_name);
|
*/
|
||||||
|
int ZFTPGetFilesize(ZftpClientType *ftp, char *file_name, uint32_t *file_size);
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: zFTP_quit()
|
/**
|
||||||
** Descriptions: ftp logout and realse the zftp_client
|
* @brief 切换服务器文件路径
|
||||||
** input parameters: ftp
|
*
|
||||||
** output parameters: None
|
* @param ftp
|
||||||
** Returned value: RT_EOK
|
* @param path
|
||||||
*********************************************************************************************************/
|
* @return int
|
||||||
int zFTP_quit(zftp_client *ftp);
|
*/
|
||||||
|
int ZFTPChangePath(ZftpClientType *ftp, char *path);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 下载对应大小的文件
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @param file_name
|
||||||
|
* @param file_size
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPDownloadFile(ZftpClientType *ftp, char *file_name, int file_size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 退出服务器
|
||||||
|
*
|
||||||
|
* @param ftp
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int ZFTPQuit(ZftpClientType *ftp);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,27 +1,24 @@
|
||||||
/****************************************Copyright (c)****************************************************
|
/****************************************Copyright (c)****************************************************
|
||||||
** fhqlongteng@163.com
|
/*
|
||||||
** QQ:283669063
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
**--------------File Info---------------------------------------------------------------------------------
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
** File name: zFTP_demo.c
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
** Last modified Date: 2020-12-01
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
** Last Version: V1.00
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
** Descriptions: zFTP demo
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
**
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
** Created by: Zhao shimin
|
* See the Mulan PSL v2 for more details.
|
||||||
** Created date: 2020-12-01
|
*/
|
||||||
** Version: V1.00
|
|
||||||
** Descriptions:
|
/*
|
||||||
**
|
* @Description: Ftp客户端功能测试
|
||||||
**
|
* @Version: V1.0.0
|
||||||
**--------------------------------------------------------------------------------------------------------
|
* @Author: 好果汁有限公司
|
||||||
** Modified by:
|
* @Date: 2023-09-24 03:59:45
|
||||||
** Modified date:
|
* @LastEditors: blackcat 18436010132@163.com
|
||||||
** Version:
|
* @LastEditTime: 2023-09-30 16:53:39
|
||||||
** Descriptions:
|
*/
|
||||||
**
|
|
||||||
** Rechecked by:
|
|
||||||
*********************************************************************************************************/
|
|
||||||
#include "./libftp/libftp.h"
|
#include "./libftp/libftp.h"
|
||||||
|
|
||||||
#ifdef ADD_XIZI_FEATURES
|
#ifdef ADD_XIZI_FEATURES
|
||||||
|
@ -29,76 +26,30 @@
|
||||||
#include <lwip/sockets.h>
|
#include <lwip/sockets.h>
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
#endif
|
#endif
|
||||||
#define PKG_USING_ZFTP 1
|
|
||||||
|
|
||||||
#ifdef PKG_USING_ZFTP
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
#define FTP_SVR_ADDR "192.168.1.100"
|
||||||
* 定义FTP的默认用户名称,服务器地址,端口等
|
|
||||||
*********************************************************************************************************/
|
|
||||||
#define FTP_SVR_ADDR "192.168.1.100" //
|
|
||||||
#define FTP_SVR_PATH "/"
|
#define FTP_SVR_PATH "/"
|
||||||
#define FTP_USER_NAME "test"
|
#define FTP_USER_NAME "test"
|
||||||
#define FTP_PASSWORD "123456"
|
#define FTP_PASSWORD "123456"
|
||||||
#define FTP_FILENAME "test.txt"
|
|
||||||
#define FIRMWARE_FLASH_PARTITION "firmware"
|
|
||||||
#define FIRMWARE_STORE_ADDR 0
|
|
||||||
|
|
||||||
static char tcp_demo_ipaddr[] = {192, 168, 1, 110};
|
|
||||||
static char tcp_demo_netmask[] = {255, 255, 255, 0};
|
|
||||||
static char tcp_demo_gwaddr[] = {192, 168, 1, 1};
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: file_read()
|
|
||||||
** Descriptions: read file from flash
|
|
||||||
** input parameters: ftp, buf, len, file_pos, total_len
|
|
||||||
** output parameters: None
|
|
||||||
** Returned value: RT_OK, ERROR
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int file_read(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t *read_len, uint32_t *total_len)
|
|
||||||
{
|
|
||||||
const struct fal_partition *partition = NULL;
|
|
||||||
|
|
||||||
*total_len = 600 * 1024;
|
|
||||||
|
|
||||||
// partition = fal_partition_find(FIRMWARE_FLASH_PARTITION);
|
|
||||||
if (partition == NULL)
|
|
||||||
{
|
|
||||||
// LOG_E("Find partition (%s) failed, Cannot save the net para!", FIRMWARE_FLASH_PARTITION);
|
|
||||||
return -ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_pos + len <= *total_len)
|
|
||||||
{
|
|
||||||
*read_len = len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*read_len = *total_len - file_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(*read_len != fal_partition_read(partition, FIRMWARE_STORE_ADDR + file_pos, buf, *read_len))
|
|
||||||
{
|
|
||||||
// LOG_E("write file error, file_pos = %d", file_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return EOK;
|
static char TcpIpAddr[] = {192, 168, 1, 110};
|
||||||
|
static char TcpNetmask[] = {255, 255, 255, 0};
|
||||||
|
static char TcpGatewayAddr[] = {192, 168, 1, 1};
|
||||||
|
|
||||||
|
/**
|
||||||
}
|
* @brief ftp客户端下载回调函数
|
||||||
|
*
|
||||||
|
* @param handle
|
||||||
|
* @param file_name
|
||||||
/*********************************************************************************************************
|
* @param buf
|
||||||
** Function name: file_write()
|
* @param len
|
||||||
** Descriptions: write file into flash
|
* @param file_pos
|
||||||
** input parameters: ftp, buf, len, file_pos, total_len
|
* @param total_len
|
||||||
** output parameters: None
|
* @return int
|
||||||
** Returned value: RT_OK, ERROR
|
*/
|
||||||
*********************************************************************************************************/
|
int FileWrite(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t total_len)
|
||||||
int file_write(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint32_t file_pos, uint32_t total_len)
|
|
||||||
{
|
{
|
||||||
//open the file in sdcard
|
//open the file in sdcard
|
||||||
FILE* fp = fopen(file_name,"a+");
|
FILE* fp = fopen(file_name,"a+");
|
||||||
|
@ -106,11 +57,8 @@ int file_write(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint3
|
||||||
printf("file open error.\n");
|
printf("file open error.\n");
|
||||||
return -ERROR;
|
return -ERROR;
|
||||||
}
|
}
|
||||||
|
printf("open file %s\n", file_name);
|
||||||
|
|
||||||
//move to file pos to write
|
|
||||||
// if(fseek(fp, file_pos, SEEK_SET) != 0){
|
|
||||||
// printf("fseek tp %d failed.\n", file_pos);
|
|
||||||
// }
|
|
||||||
int err_flag = fwrite(buf, sizeof(uint8_t),len,fp);
|
int err_flag = fwrite(buf, sizeof(uint8_t),len,fp);
|
||||||
if(err_flag<0){
|
if(err_flag<0){
|
||||||
printf("write failed,error:%d\n",err_flag);
|
printf("write failed,error:%d\n",err_flag);
|
||||||
|
@ -121,103 +69,17 @@ int file_write(void * handle, char *file_name, uint8_t *buf, uint32_t len, uint3
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: file_write()
|
|
||||||
** Descriptions: write file into flash
|
|
||||||
** input parameters: ftp, buf, len, file_pos, total_len
|
|
||||||
** output parameters: None
|
|
||||||
** Returned value: RT_OK, ERROR
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int file_erase(uint32_t file_len)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return EOK;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: cmd_ftp_download()
|
|
||||||
** Descriptions: ftp download command line
|
|
||||||
** input parameters: argc, argv
|
|
||||||
** output parameters: None
|
|
||||||
** Returned value: RT_OK, ERROR
|
|
||||||
*********************************************************************************************************/
|
|
||||||
int cmd_ftp_download(int argc, char **argv)
|
|
||||||
{
|
|
||||||
lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr);
|
|
||||||
|
|
||||||
zftp_client *ftp;
|
|
||||||
uint32_t file_size = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ftp = zFTP_login(FTP_USER_NAME, FTP_PASSWORD, FTP_SVR_ADDR);
|
|
||||||
|
|
||||||
if(ftp == NULL)
|
|
||||||
{
|
|
||||||
printf("zFTP login fail!\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zFTP_set_callback(ftp, file_write, file_read, NULL);
|
|
||||||
|
|
||||||
zFTP_change_path(ftp, FTP_SVR_PATH);
|
|
||||||
|
|
||||||
if(strcmp(argv[2], "upload") == 0)
|
|
||||||
{
|
|
||||||
if(EOK == zFTP_upload_file(ftp, argv[1]))
|
|
||||||
{
|
|
||||||
printf("zFTP upload success!\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("zFTP upload %s faile!\n", argv[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(EOK == zFTP_get_filesize(ftp, argv[1], &file_size))
|
|
||||||
{
|
|
||||||
printf("zFTP file %s size:%d!\n", argv[1], file_size);
|
|
||||||
// file_erase(file_size);
|
|
||||||
fopen(argv[1], "w+"); //清除原文件内容,实现覆盖下载文件
|
|
||||||
|
|
||||||
if(EOK == zFTP_download_file(ftp, argv[1], file_size))
|
|
||||||
{
|
|
||||||
printf("zFTP download success len: %d!\n", file_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zFTP_quit(ftp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRIV_SHELL_CMD_FUNCTION(cmd_ftp_download, a ftp client download sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
||||||
|
|
||||||
|
|
||||||
void TestFtpFileDownload(){
|
void TestFtpFileDownload(){
|
||||||
|
|
||||||
lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr);
|
lwip_config_tcp(0, TcpIpAddr, TcpNetmask, TcpGatewayAddr);
|
||||||
zftp_client *ftp;
|
ZftpClientType *ftp;
|
||||||
uint32_t file_size = 0;
|
uint32_t file_size = 0;
|
||||||
uint32_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
|
|
||||||
|
|
||||||
|
ftp = ZFTPLogin(FTP_USER_NAME, FTP_PASSWORD, FTP_SVR_ADDR);
|
||||||
ftp = zFTP_login(FTP_USER_NAME, FTP_PASSWORD, FTP_SVR_ADDR);
|
|
||||||
|
|
||||||
if(ftp == NULL)
|
if(ftp == NULL)
|
||||||
{
|
{
|
||||||
|
@ -225,17 +87,17 @@ void TestFtpFileDownload(){
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
zFTP_set_callback(ftp, file_write, file_read, NULL);
|
ZFTPSetCallback(ftp, FileWrite, NULL, NULL);
|
||||||
zFTP_change_path(ftp, FTP_SVR_PATH);
|
ZFTPChangePath(ftp, FTP_SVR_PATH);
|
||||||
for(int i=1; i<11; i++){
|
for(int i=1; i<11; i++){
|
||||||
char file_name[10] = "";
|
char file_name[10] = "";
|
||||||
sprintf(file_name, "%d.txt", i);
|
sprintf(file_name, "%d.txt", i);
|
||||||
if(EOK == zFTP_get_filesize(ftp, file_name, &file_size))
|
if(EOK == ZFTPGetFilesize(ftp, file_name, &file_size))
|
||||||
{
|
{
|
||||||
printf("zFTP file %s size:%d!\n", file_name, file_size);
|
printf("zFTP file %s size:%d!\n", file_name, file_size);
|
||||||
fopen(file_name, "w+"); //清除原文件内容,实现覆盖下载文件
|
fopen(file_name, "w+"); //清除原文件内容,实现覆盖下载文件
|
||||||
|
|
||||||
if(EOK == zFTP_download_file(ftp, file_name, file_size))
|
if(EOK == ZFTPDownloadFile(ftp, file_name, file_size))
|
||||||
{
|
{
|
||||||
printf("zFTP download success len: %d!\n", file_size);
|
printf("zFTP download success len: %d!\n", file_size);
|
||||||
}
|
}
|
||||||
|
@ -245,14 +107,8 @@ void TestFtpFileDownload(){
|
||||||
printf("All download finished. Total size: %d\n", total_size);
|
printf("All download finished. Total size: %d\n", total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
zFTP_quit(ftp);
|
ZFTPQuit(ftp);
|
||||||
}
|
}
|
||||||
PRIV_SHELL_CMD_FUNCTION(TestFtpFileDownload, a ftp client test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
PRIV_SHELL_CMD_FUNCTION(TestFtpFileDownload, a ftp client test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** End of file
|
|
||||||
*********************************************************************************************************/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue