2023_open_source_contest_preliminary_1st_issue3

This commit is contained in:
Oscar 2023-10-04 10:59:25 +08:00
parent a1df906d16
commit 7af778fd67
21 changed files with 447 additions and 1 deletions

View File

@ -134,7 +134,7 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
endif
ifeq ($(CONFIG_USER_TEST_FTPCLIENT),y)
SRC_FILES +=
SRC_FILES += test_ftpclient/test_ftpclient.c
endif
ifeq ($(CONFIG_USER_TEST_LORA_P2P),y)

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,70 @@
# 基于矽璓已实现的Lwip在ARM上实现FTP协议的Client功能并测试验证 ##
## 1. 简介
基于XiUOS中的Lwip协议和提供的接口实现了FTP客户端的基本功能包括登录(验证用户账号和密码)、文件目录显示(ls)、文件目录进入(cd)、文件下载等。
按照题目要求FTP服务器端搭建在我们队员的个人电脑上系统版本为Windows10专业版利用Windows自带的Internet Information Services (IIS) 6.0 管理器对自定义FTP站点进行了创建及管理。
此外我们还借助FileZilla Server Interface在实现过程中辅助监测连接与传输情况但最后提交代码所实现的数据上传下载实现过程不涉及FileZilla使用。
## 2. 函数功能设计说明
`FillServerAddr`Bind the server IP address <br />
`CreateControlConnection`Create a control connection <br />
`CreateDataConnection`Create a data connection <br />
`GetReplyMsg`Get a reply message <br />
`SendControlCommand`Send control command <br />
`LoginServer`Logging In to the FTP Server <br />
`PasvInitiateFileDownload`Before downloading the file, send the PASV command to enter passive mode, and the FTP server will open a new port for receiving the file data. <br />
`FileDownload`Download the file from the server <br />
`ListCurrentDirectory`Implement the ls command to display the files and directories in the current directory <br />
`ChangeDirectory`Run the cd command to go to the target directory <br />
`Quit`Log out of the server <br />
`TestFTPClient`The function we used to test FTP client, realized . <br />
## 3. 测试程序说明
在ARM终端上实现了FTP Client的功能
## 4. 运行结果(##需结合运行测试截图按步骤说明##
① 编译及开启本地FTP服务器准备<br />
![image](pre1-EnableLwIP.JPG) <br />
menuconfig中使能LwIP网络协议栈
![image](pre2-ConfigOpen.JPG) <br />
打开menuconfig之后将test ftp client开启(y),保存后退出
![image](pre3-CompileSuccess.JPG) <br />
使用
“make BOARD=edu-arm32 distclean <br />
make BOARD=edu-arm32 menuconfig <br />
make BOARD=edu-arm32”命令编译XiZi-edu-arm32.bin成功编译得到的“XiZi-edu-arm32.bin”文件我们已附在文件夹中供评委检验。 <br />
![image](pre4-OpenFTPService.png) <br />
打开控制面板选择“程序”点击“启用或关闭Windows功能”。选择"Internet Information Services"下的FTP服务器中的FTP服务复选框同时勾选web管理工具下的IIS管理控制台。<br />
![image](pre5-SetFTP1.png) <br />
win+R输入inetmgr打开IIS管理器设置站点名称、IP地址、存储物理路径、SSL设置方便起见可设置无SSL、身份验证设置匿名或授权访问均可可自行生成所需SSL证书等。
![image](pre6-SetFTP2.png) <br />
之后关闭电脑防火墙以防数据被误拦截在身份验证时输入账号密码登录FTP服务器通过身份验证本地FTP服务器准备即告完成。
② 测试ARM终端数据下载
![image](01-FilesInFTPServer.png) <br />
首先展示本地FTP服务器存放的测试文件每个文件均为自动化脚本生成大小为严格的4KB。 <br />
![image](02-OpenFTPServer.png) <br />
启动本地FTP服务器确保连接。 <br />
![image](03-beforeDownload.png) <br />
首先通过ls命令展示ARM终端现有的文件情况可以看到目前仅有2个之前生成的测试用文件我们可以将其忽略。 <br />
![image](04-downloading1.png) <br />
![image](05-downloading2.png) <br />
![image](06-downloading3.png) <br />
![image](07-downloading4.png) <br />
![image](08-downloading5.png) <br />
![image](09-downloading6.png) <br />
输入执行TestFTPClient命令ARM终端作为客户端开始访问服务器端下载指定的10个大小为4KB的.txt文件。对于每个文件的数据端口访问及接受数据、下载情况打印出的提示信息中均有详细解释。 <br />
![image](10-downloadedFileList.png) <br />
下载完成后再次使用ls命令展示ARM终端作为客户端访问服务器端下载指定的10个大小为4KB的.txt文件可以看到相比最开始终端上多了10个大小为4KB的文件即一开始存放在本地服务器上的文件。 <br />

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -0,0 +1,313 @@
/*
* Copyright (c) 2023 AIIT Ubiquitous Team
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL
v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* 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.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: test_ftpclient.c
* @brief: Based on the protocol Lwip in XiUOS and the interface provided, this
file realized the basic functions of the FTP client, including login (verifying
user account and password), file directory display (ls), file directory entry (cd),
file download, etc.
* @version: 1.0
* @author: Oscar
* @date: 2023/8/25
*/
#include <transform.h>
#include "test_ftpclient.h"
struct sockaddr_in ftp_server_ctrl_addr; // Saves information about the control connection
struct sockaddr_in ftp_server_data_addr; // Saves data connection information
int sockfd_ctrl; // The socket that controls the connection
int sockfd_data; // The socket for the data connection
char server_ip_str[20]; // ip address of the FTP server
int server_port; // Port number of the FTP server
char msg_buffer[MAX_BUF_LEN]; // Message sent to the FTP server
char data_buffer[MAX_BUF_LEN]; // Send or receive data from the FTP server
/**
* @description: Bind the server IP address
* @param ip - ip address
* @param port - server port
* @param str_server_addr - struct for save ip information
* @return void
*/
void FillServerAddr(const char* ip, unsigned short int port,struct sockaddr_in* str_server_addr)
{
memset(str_server_addr, 0,sizeof(struct sockaddr_in));
str_server_addr->sin_family = AF_INET;
str_server_addr->sin_port = htons(port);
str_server_addr->sin_addr.s_addr = inet_addr(ip);
}
/**
* @description: Create a control connection
* @return 0 means success, -1 means fail
*/
int CreateControlConnection()
{
sockfd_ctrl = socket(AF_INET, SOCK_STREAM, 0); // create socket descriptor
if(sockfd_ctrl == -1){
printf("[Error] Create socket failed!\n");
return -1;
}
printf("[Info] create socket success.\nbegin to connect.\n");
if(connect(sockfd_ctrl,(struct sockaddr *)&ftp_server_ctrl_addr,sizeof(struct sockaddr)) == 0){ // connect to the server
printf("Successfully connect to server:ip:%s,port:%d\n",
inet_ntoa(ftp_server_ctrl_addr.sin_addr) ,ntohs(ftp_server_ctrl_addr.sin_port));
}else{
printf("[Error] control connect failed!\n");
return -1;
}
return 0;
}
/**
* @description: Create a data connection
* @return 0 means success, -1 means fail
*/
int CreateDataConnection()
{
sockfd_data = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd_data == -1){
printf("[Error] Create socket failed!");
return -1;
}
if (connect(sockfd_data, (struct sockaddr*)&ftp_server_data_addr, sizeof(struct sockaddr_in)) == 0){
printf("[Info] Successfully connect to server:ip:%s,port:%d\n", inet_ntoa(ftp_server_data_addr.sin_addr), ntohs(ftp_server_data_addr.sin_port));
}else{
printf("[Error] data connect failed!\n");
return -1;
}
return 0;
}
/**
* @description: Get a reply message
* @return void
*/
int GetReplyMsg()
{
int receive_byte_count, reply;
memset(msg_buffer, 0, MAX_BUF_LEN);
receive_byte_count = lwip_read(sockfd_ctrl, msg_buffer, MAX_BUF_LEN);
reply = atoi(msg_buffer);
printf("[Info] receive bytes: %d, Server reply: %s\n", receive_byte_count, msg_buffer);
return reply;
}
/**
* @description: Send control command
* @param send_msg - message need send
* @return void
*/
void SendControlCommand(const char* send_msg)
{
send(sockfd_ctrl, send_msg, strlen(send_msg), 0);
printf("[Info] Send tcp msg: %s\n", send_msg);
}
/**
* @description: Logging In to the FTP Server
* @param username - server login username
* @param password - server login password
* @return 0 means success, -1 means fail
*/
int LoginServer(char *username, char *password)
{
if (NULL == username || NULL == password) {
printf("[Error] username or password can not be NULL\n");
return -1;
}
sprintf(msg_buffer, "USER %s\r\n", username);
SendControlCommand(msg_buffer);
GetReplyMsg();
sprintf(msg_buffer, "PASS %s\r\n", password);
SendControlCommand(msg_buffer);
if (230 == GetReplyMsg())
return 0;
else
return -1;
}
/**
* @description: Before downloading the file, send the PASV command to enter passive mode, and the FTP server will open a new port for receiving the file data.
* @return the new port for data connection
*/
int PasvInitiateFileDownload()
{
int passive_port = -1;
SendControlCommand("PASV\r\n");
GetReplyMsg();
char *ip_and_port_str = strrchr(msg_buffer, '(');
int ip_first, ip_second, ip_third, ip_fourth, high_port, low_port;
sscanf(ip_and_port_str, "(%d,%d,%d,%d,%d,%d)", &ip_first, &ip_second, &ip_third, &ip_fourth, &high_port, &low_port);
passive_port = high_port * 256 + low_port;
return passive_port;
}
/**
* @description: Download the file from the server
* @param filename - name of download file
* @return void
*/
void FileDownload(char *filename)
{
if (NULL == filename) {
printf("[Error] file name can not be NULL");
return;
}
SendControlCommand("TYPE I\r\n");
GetReplyMsg();
sprintf(msg_buffer,"SIZE %s\r\n",filename);
SendControlCommand(msg_buffer);
GetReplyMsg();
int file_size = atoi(msg_buffer + 4);
printf("[Info] %s filesize: %d\n", filename, file_size);
// passive
int passive_port = PasvInitiateFileDownload();
if (passive_port > 0)
FillServerAddr(server_ip_str, passive_port, &ftp_server_data_addr);
sprintf(msg_buffer,"RETR %s\r\n",filename);
SendControlCommand(msg_buffer);
if (CreateDataConnection() < 0){
printf("[Error] unable to connect data port\n");
return;
}
GetReplyMsg();
// create file and write message to file
int file_fd = PrivOpen(filename,O_RDWR | O_CREAT);
if (file_fd < 0){
printf("[Error] error to open file!\n");
}
printf("[Info] begin to download %s\n",filename);
int download_bytes_count = 0, current_download_bytes_count = 0;
memset(data_buffer,0,sizeof(data_buffer));
while ((current_download_bytes_count = lwip_read(sockfd_data,data_buffer,MAX_BUF_LEN)) > 0){
PrivWrite(file_fd,data_buffer, current_download_bytes_count);
download_bytes_count += current_download_bytes_count;
printf("== %d/%d bytes received\n", download_bytes_count, file_size);
}
printf("[Info] total %d bytes received. download %s succeed.\n", download_bytes_count, filename);
lwip_close(sockfd_data);
PrivClose(file_fd);
}
/**
* @description: Implement the ls command to display the files and directories in the current directory
* @return void
*/
void ListCurrentDirectory()
{
int passive_port = PasvInitiateFileDownload();
if (passive_port > 0)
FillServerAddr(server_ip_str, passive_port, &ftp_server_data_addr);
SendControlCommand("LIST\r\n");
if (CreateDataConnection() < 0){
printf("[Error] unable to connect data port\n");
return;
}
printf("[Info] Recving data! please wait....\n");
int receive_bytes_count = lwip_read(sockfd_data, data_buffer, MAX_BUF_LEN);
printf("%s\n", data_buffer);
lwip_close(sockfd_data);
}
/**
* @description: Run the cd command to go to the target directory
* @param pathname - target directory
* @return void
*/
void ChangeDirectory(char *pathname)
{
if (NULL == pathname) {
printf("[Error] path name can not be NULL\n");
return;
}
sprintf(msg_buffer,"CWD %s\r\n",pathname);
SendControlCommand(msg_buffer);
GetReplyMsg();
}
/**
* @description: Log out of the server
* @return void
*/
void Quit()
{
SendControlCommand("QUIT\r\n");
GetReplyMsg();
lwip_close(sockfd_ctrl);
}
/**
* @description: Test FTP client.
*/
void TestFTPClient(int argc, char* argv[])
{
printf("-------------------Config Network-------------------\n");
// Set an ip address for the development board
char board_ipaddr[] = { 192, 168, 1, 103 }; // ip address of the development board to be set
char board_netmask[] = { 255, 255, 255, 0 }; // Subnet mask of the development board
char board_gwaddr[] = { 192, 168, 1, 0 }; // Development board gateway
lwip_config_tcp(0, board_ipaddr, board_netmask, board_gwaddr);
// connect
printf("-------------------Connect-------------------\n");
char connect_ip_addr[] = "192.168.1.100";// ftp server ipaddr
int connect_port = 21; // ftp server port
sprintf(server_ip_str,connect_ip_addr);
server_port = connect_port;
FillServerAddr(server_ip_str, server_port, &ftp_server_ctrl_addr);
CreateControlConnection();
GetReplyMsg();
// login, set username and password here
printf("-------------------Login-------------------\n");
char username[] = "linha";
char password[] = "guoji123";
if (LoginServer(username, password) == 0){
printf("success login.\n");
}
else{
printf("login fail.\n");
return;
}
// TestFTPClient
printf("-------------------TestFTPClient-------------------\n");
printf("-------------------List Directory-------------------\n");
ListCurrentDirectory(); // ls
printf("-------------------Change Directory-------------------\n");
char change_to_directory[] = "file";
ChangeDirectory(change_to_directory); // cd file
printf("-------------------List 10 files need to download-------------------\n");
ListCurrentDirectory(); // ls
printf("-------------------Download 10 files-------------------\n");
char test_files[][10] = {"foo.txt", "baz.txt", "bar.txt", "tab.txt", "tap.txt", "out.txt", "hot.txt", "egg.txt", "cat.txt", "num.txt"};
for (int i = 0; i < 10; i++) {
FileDownload(test_files[i]); // download
}
printf("-------------------Quit-------------------\n");
Quit(); // quit
}
PRIV_SHELL_CMD_FUNCTION(TestFTPClient, a simple test FTPClient sample, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 AIIT Ubiquitous Team
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL
v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* 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.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: test_ftpclient.h
* @brief: Based on the protocol Lwip in XiUOS and the interface provided, this
file realized the basic functions of the FTP client, including login (verifying
user account and password), file directory display (ls), file directory entry (cd),
file download, etc.
* @version: 1.0
* @author: Oscar
* @date: 2023/8/25
*/
#include <stdio.h>
#include <sys_arch.h>
#include "lwip/sockets.h"
#define MAX_BUF_LEN 4096 // Maximum cache bytes 4k
// Bind the server IP address
void FillServerAddr(const char* ip, unsigned short int port, struct sockaddr_in* pServer_addr);
// Create a control connection
int CreateControlConnection();
// Create a data connection
int CreateDataConnection();
// Get a reply message
int GetReplyMsg(void);
// Send control command
void SendControlCommand(const char* send_msg);
// Logging In to the FTP Server
int LoginServer(char* username, char* password);
// Before downloading the file, send the PASV command to enter passive mode, and the
// FTP server will open a new port for receiving the file data.
int PasvInitiateFileDownload();
// Download the file from the server
void FileDownload(char* filename);
// Implement the ls command to display the files and directories in the current
// directory
void ListCurrentDirectory();
// Run the cd command to go to the target directory
void ChangeDirectory(char* pathname);
// Log out of the server
void Quit(void);