2023_open_source_contest_final_1st_issue3 from 华东师范大学_bdislab_final战队_杨龙
it is OK
| 
						 | 
					@ -159,5 +159,9 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
 | 
				
			||||||
        SRC_FILES += 
 | 
					        SRC_FILES += 
 | 
				
			||||||
    endif
 | 
					    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ifeq ($(CONFIG_USER_TEST_FTPCLIENT_FINAL),y)
 | 
				
			||||||
 | 
					        SRC_FILES += test_ftpclient_final/test_ftpclient_final.c test_ftpclient_final/ftp_client/ftp_client.c test_ftpclient_final/ftp_client/my_socket.c
 | 
				
			||||||
 | 
					    endif   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    include $(KERNEL_ROOT)/compiler.mk
 | 
					    include $(KERNEL_ROOT)/compiler.mk
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,135 @@
 | 
				
			||||||
 | 
					# 决赛一级赛题3:基于初赛一级赛题3,在云服务器上实现FTP Server功能
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 1. 简介
 | 
				
			||||||
 | 
					本项目是基于赛事提供的云服务器,实现FTP协议的Server功能,其功能支持至少10个Client端并发向Server端传输4KB大小的文件,
 | 
				
			||||||
 | 
					支持Server端并发地向至少10个Client端传输4KB大小的文件。
 | 
				
			||||||
 | 
					test_ftpclient_final.h声明了多个客户端并发下载文件、并发上传文件的测试函数
 | 
				
			||||||
 | 
					test_ftpclient_final.c实现了多个客户端并发下载文件、并发上传文件的测试函数
 | 
				
			||||||
 | 
					ftp_client文件夹定义了ftp_client的相关类库其中my_socket.h,my_socket.c定义了socket抽象层,并基于
 | 
				
			||||||
 | 
					Lwip实现了该抽象层,ftp_client.h,ftp_client.c实现了ftp登录,获取文件大小,下载文件等功能
 | 
				
			||||||
 | 
					注意:在赛事提供的云服务器/root/yanglongFTP上有对应服务器代码 ./server运行服务器,为了方便查看代码我们讲服务器代码备份存放在ftp_server目录下
 | 
				
			||||||
 | 
					## 2. 数据结构设计说明
 | 
				
			||||||
 | 
					- ftp_client.c 的设计
 | 
				
			||||||
 | 
					分别定义了发送命令和接收数据的socket和相应的缓冲区并且实现了登录、发送命令、接收响应数据、查找文件大小、进入被动模式、下载文件、关闭ftp客户端等操作
 | 
				
			||||||
 | 
					```c
 | 
				
			||||||
 | 
					static int  m_socket_cmd[THREAD_NUM]; // 发送命令的socket文件描述符,THREAD_NUM表示线程数目,用来模拟多个客户端并发访问
 | 
				
			||||||
 | 
					static int  m_socket_data[THREAD_NUM]; // 接收ftp服务器文件的socket文件描述符
 | 
				
			||||||
 | 
					static char m_send_buffer[THREAD_NUM][1024]; // 发送缓冲区
 | 
				
			||||||
 | 
					static char m_recv_buffer[THREAD_NUM][1024]; // 接收缓冲区
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					- server.c 的设计(具体代码在赛事提供的云服务器的/root/yanglongFTP下)
 | 
				
			||||||
 | 
					```c
 | 
				
			||||||
 | 
					#define THREAD_NUM 10000 // thread num
 | 
				
			||||||
 | 
					static int isBinary = 0; // transmit binary data
 | 
				
			||||||
 | 
					static int port = 9992; // service port
 | 
				
			||||||
 | 
					static int dataPort = 9993; // the port for file download
 | 
				
			||||||
 | 
					static char order[4]; // receive order
 | 
				
			||||||
 | 
					static char param[20]; // receive order param
 | 
				
			||||||
 | 
					static char *respMessage; // respose message
 | 
				
			||||||
 | 
					static int serverFd;  // the server fd for deal with order requests
 | 
				
			||||||
 | 
					static int dataServerFd; // the server fd for file download
 | 
				
			||||||
 | 
					sem_t mutex; // mutex lock
 | 
				
			||||||
 | 
					struct Data{ // 线程间通信传输的数据
 | 
				
			||||||
 | 
					    char fileName[20]; // file name
 | 
				
			||||||
 | 
					    int type; // 0:download 1:upload
 | 
				
			||||||
 | 
					    sem_t isDone;  // complete file downlaod
 | 
				
			||||||
 | 
					    sem_t isReady;  // 文件准备好了
 | 
				
			||||||
 | 
					} data;
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					## 3. 测试程序说明
 | 
				
			||||||
 | 
					- test_ftpclient_final.c用于测试多个客户端并发下载文件
 | 
				
			||||||
 | 
					通过多线程模拟多个客户端并发访问服务器,通过 TestFtpClient options threads进行测试
 | 
				
			||||||
 | 
					其中options=1表示下载options=2表示上传,threads表示线程数/模拟的并发客户端数目
 | 
				
			||||||
 | 
					```c
 | 
				
			||||||
 | 
					/* test for 10 ftp client */
 | 
				
			||||||
 | 
					void TestFtpClient(int argc, char* argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int options = atoi(argv[1]);
 | 
				
			||||||
 | 
					    int n = atoi(argv[2]);
 | 
				
			||||||
 | 
					    pthread_t threads[THREAD_NUM];
 | 
				
			||||||
 | 
					    for(int i = 0;i < n;++i){
 | 
				
			||||||
 | 
					        threadIDs[i] = i;
 | 
				
			||||||
 | 
					        if(options == 1){ // 全部都是下载
 | 
				
			||||||
 | 
					            pthread_create(&threads[i],NULL,&DownLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					        }else if(options == 2){ // 全部都是上传
 | 
				
			||||||
 | 
					            pthread_create(&threads[i],NULL,&UpLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					        }else if(options == 3){  // 随机下载/上传
 | 
				
			||||||
 | 
					            int r = rand()%2;
 | 
				
			||||||
 | 
					            if(r == 0){
 | 
				
			||||||
 | 
					                printf("===============download===============\n");
 | 
				
			||||||
 | 
					                pthread_create(&threads[i],NULL,&DownLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					            }else{
 | 
				
			||||||
 | 
					                printf("===============upload===============\n");
 | 
				
			||||||
 | 
					                pthread_create(&threads[i],NULL,&UpLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					PRIV_SHELL_CMD_FUNCTION(TestFtpClient, a ftpClient test sample, PRIV_SHELL_CMD_MAIN_ATTR);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 4. 运行结果(##需结合运行测试截图按步骤说明##)
 | 
				
			||||||
 | 
					1. 配置开启BSP_USING_LWIP、USER_TEST_FTPCLIENT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. 编译
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. 烧写
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. xshell连接串口终端并配置ip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. 通过./server在云服务器运行FTP服务器
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					6. 运行TestFtpClient 1 10,模拟10个客户端并发下载文件
 | 
				
			||||||
 | 
					- 客户端日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 服务器日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					7. 运行TestFtpClient 2 10,模拟10个客户端并发上传文件
 | 
				
			||||||
 | 
					- 客户端日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 服务器日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 上传结果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					8. 运行TestFtpClient 3 10,模拟10个客户端混合并发下载和上传文件
 | 
				
			||||||
 | 
					- 客户端日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 服务器日志
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 下载和上传结果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,299 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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:    ftp_client.c
 | 
				
			||||||
 | 
					* @brief:   ftp client tool
 | 
				
			||||||
 | 
					* @version: 1.0
 | 
				
			||||||
 | 
					* @author:  bdislab_final
 | 
				
			||||||
 | 
					* @date:    2023/9/16
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include "my_socket.h"
 | 
				
			||||||
 | 
					#include "ftp_client.h"
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int  m_socket_cmd[THREAD_NUM];
 | 
				
			||||||
 | 
					static int  m_socket_data[THREAD_NUM];
 | 
				
			||||||
 | 
					static char m_send_buffer[THREAD_NUM][1024];
 | 
				
			||||||
 | 
					static char m_recv_buffer[THREAD_NUM][1024];
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					static int FtpSendCommand(int threadID,char *cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						printf("send command: %s,threadID=%d\r\n", cmd,threadID);
 | 
				
			||||||
 | 
						ret = SocketSend(m_socket_cmd[threadID], cmd, (int)strlen(cmd));
 | 
				
			||||||
 | 
						if(ret < 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("failed to send command: %s\r\n",cmd);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					static int FtpRecvRespond(int threadID,char *resp, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						int off;
 | 
				
			||||||
 | 
						len -= 1;
 | 
				
			||||||
 | 
						for(off=0; off<len; off+=ret)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ret = SocketRecv(m_socket_cmd[threadID], &resp[off], 1);
 | 
				
			||||||
 | 
							if(ret < 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								printf("recv respond error(ret=%d)!\r\n", ret);
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if(resp[off] == '\n')
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						resp[off+1] = 0;
 | 
				
			||||||
 | 
						printf("respond:%s,threadID=%d\r\n", resp,threadID);
 | 
				
			||||||
 | 
						return atoi(resp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					static int FtpEnterPasv(int threadID,char *ipaddr, int *port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						char *find;
 | 
				
			||||||
 | 
						int a,b,c,d;
 | 
				
			||||||
 | 
						int pa,pb;
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,"PASV\r\n");
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 227)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						find = strrchr(m_recv_buffer[threadID], '(');
 | 
				
			||||||
 | 
						sscanf(find, "(%d,%d,%d,%d,%d,%d)", &a, &b, &c, &d, &pa, &pb);
 | 
				
			||||||
 | 
						sprintf(ipaddr, "%d.%d.%d.%d", a, b, c, d);
 | 
				
			||||||
 | 
						*port = pa * 256 + pb;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  FtpUpload(int threadID,char *name, void *buf, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int  ret;
 | 
				
			||||||
 | 
						char ipaddr[32];
 | 
				
			||||||
 | 
						int  port;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						//查询数据地址
 | 
				
			||||||
 | 
						ret=FtpEnterPasv(threadID,ipaddr, &port);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret=SocketConnect(m_socket_data[threadID], ipaddr, port);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//准备上传
 | 
				
			||||||
 | 
						sprintf(m_send_buffer[threadID], "STOR %s\r\n", name);
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,m_send_buffer[threadID]);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 150)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_data[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						//开始上传
 | 
				
			||||||
 | 
						ret = SocketSend(m_socket_data[threadID], buf, len);
 | 
				
			||||||
 | 
						if(ret != len)
 | 
				
			||||||
 | 
						{	
 | 
				
			||||||
 | 
							printf("send data error!\r\n");
 | 
				
			||||||
 | 
							SocketClose(m_socket_data[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SocketClose(m_socket_data[threadID]);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
						//上传完成,等待回应
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						return (ret==226);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  FtpDownload(int threadID,char *name, void *buf, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int   i;
 | 
				
			||||||
 | 
						int   ret;
 | 
				
			||||||
 | 
						char  ipaddr[32];
 | 
				
			||||||
 | 
						int   port;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
						//查询数据地址
 | 
				
			||||||
 | 
						ret = FtpEnterPasv(threadID,ipaddr, &port);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("m_socket_data[threadID]=%d,threadID=%d\n",m_socket_data[threadID],threadID);
 | 
				
			||||||
 | 
						//连接数据端口
 | 
				
			||||||
 | 
						ret = SocketConnect(m_socket_data[threadID], ipaddr, port);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("failed to connect data port\r\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
						//准备下载
 | 
				
			||||||
 | 
						sprintf(m_send_buffer[threadID], "RETR %s\r\n", name);
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,m_send_buffer[threadID]);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 150)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_data[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						//开始下载,读取完数据后,服务器会自动关闭连接
 | 
				
			||||||
 | 
						for(i=0; i<len; i+=ret)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ret = SocketRecv(m_socket_data[threadID], ((char *)buf) + i, len);
 | 
				
			||||||
 | 
							printf("download %d/%d.,threadID=%d\r\n", i + ret, len,threadID);
 | 
				
			||||||
 | 
							if(ret < 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								printf("download was interrupted.\r\n");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//下载完成
 | 
				
			||||||
 | 
						printf("download %d/%d bytes complete.,threadID=%d\r\n", i, len,threadID);
 | 
				
			||||||
 | 
					    // FILE *fp = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // fp = fopen(name+1, "wb");
 | 
				
			||||||
 | 
					    // fwrite(buf,len,1,fp);
 | 
				
			||||||
 | 
					    // fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SocketClose(m_socket_data[threadID]);
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						return (ret==226);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					int  FtpFileSize(int threadID,char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						int size;
 | 
				
			||||||
 | 
						sprintf(m_send_buffer[threadID],"SIZE %s\r\n",name);
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,m_send_buffer[threadID]);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 213)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size = atoi(m_recv_buffer[threadID] + 4);
 | 
				
			||||||
 | 
						return size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					int FtpLogin(int threadID,char *addr, int port, char *username, char *password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						printf("connect...,threadID=%d\r\n",threadID);
 | 
				
			||||||
 | 
						ret = SocketConnect(m_socket_cmd[threadID], addr, port);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("connect server failed!\r\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("connect ok.,threadID=%d\r\n",threadID);
 | 
				
			||||||
 | 
					    //等待欢迎信息
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 220)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("bad server, ret=%d!\r\n", ret);
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						printf("login...threadID=%d\r\n",threadID);
 | 
				
			||||||
 | 
					    //发送USER
 | 
				
			||||||
 | 
						sprintf(m_send_buffer[threadID], "USER %s\r\n", username);
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,m_send_buffer[threadID]);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 331)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    //发送PASS
 | 
				
			||||||
 | 
						sprintf(m_send_buffer[threadID], "PASS %s\r\n", password);
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,m_send_buffer[threadID]);
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 230)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("login success.threadID=%d\r\n",threadID);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    //设置为二进制模式
 | 
				
			||||||
 | 
						ret = FtpSendCommand(threadID,"TYPE I\r\n");
 | 
				
			||||||
 | 
						if(ret != 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret = FtpRecvRespond(threadID,m_recv_buffer[threadID], 1024);
 | 
				
			||||||
 | 
						if(ret != 200)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					void FtpQuit(int threadID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FtpSendCommand(threadID,"QUIT\r\n");
 | 
				
			||||||
 | 
						SocketClose(m_socket_cmd[threadID]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					void FtpInitCmd(int threadID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_socket_cmd[threadID] = SocketCreate();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FtpInitData(int threadID){
 | 
				
			||||||
 | 
					    m_socket_data[threadID]= SocketCreate();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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:    ftp_client.h
 | 
				
			||||||
 | 
					* @brief:   ftp client tool
 | 
				
			||||||
 | 
					* @version: 1.0
 | 
				
			||||||
 | 
					* @author:  bdislab_final
 | 
				
			||||||
 | 
					* @date:    2023/9/16
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FTP_CLIENT_H
 | 
				
			||||||
 | 
					#define FTP_CLIENT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define THREAD_NUM 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* init ftp cmd socket */ 
 | 
				
			||||||
 | 
					void FtpInitCmd(int threadID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* init ftp data socket */
 | 
				
			||||||
 | 
					void FtpInitData(int threadID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* quit ftp */
 | 
				
			||||||
 | 
					void FtpQuit(int threadID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* fpt login */
 | 
				
			||||||
 | 
					int  FtpLogin(int threadID,char *addr, int port, char *username, char *password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* get file size */
 | 
				
			||||||
 | 
					int  FtpFileSize(int threadID,char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ftp download file*/
 | 
				
			||||||
 | 
					int  FtpDownload(int threadID,char *name, void *buf, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*ftp upload*/
 | 
				
			||||||
 | 
					int  FtpUpload(int threadID,char *name, void *buf, int len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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:    my_socket.c
 | 
				
			||||||
 | 
					* @brief:   a abstract socket api
 | 
				
			||||||
 | 
					* @version: 1.0
 | 
				
			||||||
 | 
					* @author:  bdislab_final
 | 
				
			||||||
 | 
					* @date:    2023/9/16
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "my_socket.h"
 | 
				
			||||||
 | 
					#include <sockets.h>
 | 
				
			||||||
 | 
					#include <def.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  SocketCreate(void){
 | 
				
			||||||
 | 
					    return socket(AF_INET,SOCK_STREAM,0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  SocketConnect(int sock, const char *addr, int port){
 | 
				
			||||||
 | 
						// unsigned int iRemoteAddr = 0;
 | 
				
			||||||
 | 
						struct sockaddr_in stRemoteAddr = {0}; //对端,即目标地址信息
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						stRemoteAddr.sin_family = AF_INET;
 | 
				
			||||||
 | 
						stRemoteAddr.sin_port = htons(port);
 | 
				
			||||||
 | 
						stRemoteAddr.sin_addr.s_addr = inet_addr(addr);
 | 
				
			||||||
 | 
						int res = connect(sock,(struct sockaddr *)&stRemoteAddr,sizeof(stRemoteAddr));
 | 
				
			||||||
 | 
						if(res == -1){
 | 
				
			||||||
 | 
							printf("error:%d,str error:%s\n",errno,strerror(errno));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    return res == 0 ? 1 : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  SocketSend(int sock, void *data, int len){
 | 
				
			||||||
 | 
					    return send(sock,data,len,0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int  SocketRecv(int sock, void *data, int len){
 | 
				
			||||||
 | 
					    return recv(sock,data,len,0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SocketClose(int sock){
 | 
				
			||||||
 | 
						close(sock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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 my_socket.h
 | 
				
			||||||
 | 
					 * @brief a abstract socket api
 | 
				
			||||||
 | 
					 * @version 1.0
 | 
				
			||||||
 | 
					 * @author bdislab_final
 | 
				
			||||||
 | 
					 * @date 2023/9/16
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MYSOCKET_H
 | 
				
			||||||
 | 
					#define MYSOCKET_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					/* create a socket */
 | 
				
			||||||
 | 
					int  SocketCreate(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* connect a socket */
 | 
				
			||||||
 | 
					int  SocketConnect(int sock, const char *addr, int port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* send data through socket*/
 | 
				
			||||||
 | 
					int  SocketSend(int sock, void *data, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* receive data from socket*/
 | 
				
			||||||
 | 
					int  SocketRecv(int sock, void *data, int len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* close socket*/
 | 
				
			||||||
 | 
					void SocketClose(int sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					for i in {1..10}
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						dd if=/dev/zero of="file$i" bs=4K count=1
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,251 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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:    server.c
 | 
				
			||||||
 | 
					* @brief:   a ftpserver
 | 
				
			||||||
 | 
					* @version: 1.0
 | 
				
			||||||
 | 
					* @author:  bdislab_final
 | 
				
			||||||
 | 
					* @date:    2023/10/11
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					#include <semaphore.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define THREAD_NUM 10000 // thread num
 | 
				
			||||||
 | 
					static int isBinary = 0; // transmit binary data
 | 
				
			||||||
 | 
					static int port = 9992; // service port
 | 
				
			||||||
 | 
					static int dataPort = 9993; // the port for file download
 | 
				
			||||||
 | 
					static char order[4]; // receive order
 | 
				
			||||||
 | 
					static char param[20]; // receive order param
 | 
				
			||||||
 | 
					static char *respMessage; // respose message
 | 
				
			||||||
 | 
					static int serverFd;  // the server fd for deal with order requests
 | 
				
			||||||
 | 
					static int dataServerFd; // the server fd for file download
 | 
				
			||||||
 | 
					sem_t mutex; // mutex lock
 | 
				
			||||||
 | 
					struct Data{ // 线程间通信传输的数据
 | 
				
			||||||
 | 
					    char fileName[20]; // file name
 | 
				
			||||||
 | 
					    int type; // 0:download 1:upload
 | 
				
			||||||
 | 
					    sem_t isDone;  // complete file downlaod
 | 
				
			||||||
 | 
					    sem_t isReady;  // 文件准备好了
 | 
				
			||||||
 | 
					} data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RecvData(int clientFd,char param[20]){
 | 
				
			||||||
 | 
					    recv(clientFd,param,20,0);
 | 
				
			||||||
 | 
					    for(int i = 0;i < 20;++i){
 | 
				
			||||||
 | 
					        if(param[i] == '\r'){
 | 
				
			||||||
 | 
					            param[i] = '\0';
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SendMessage(int clientFd, char * respMessage){
 | 
				
			||||||
 | 
					    int len = 0;
 | 
				
			||||||
 | 
					    while(respMessage[len] != '\n'){
 | 
				
			||||||
 | 
					        len++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    send(clientFd,respMessage,len+1,0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int CreateServer(int port,int type) {
 | 
				
			||||||
 | 
					    int serverFd = 0;
 | 
				
			||||||
 | 
						struct sockaddr_in serverAddr = {0};
 | 
				
			||||||
 | 
						socklen_t socklen = 0;
 | 
				
			||||||
 | 
						serverFd = socket(AF_INET, SOCK_STREAM, 0);
 | 
				
			||||||
 | 
						if(0 > serverFd)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("创建socket失败\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(type == 0){
 | 
				
			||||||
 | 
					        printf("in ftp server:serverFd=%d\n",serverFd);
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					        printf("in ftp data server:serverFd=%d\n",serverFd);
 | 
				
			||||||
 | 
					    }	
 | 
				
			||||||
 | 
						serverAddr.sin_family = AF_INET;
 | 
				
			||||||
 | 
						serverAddr.sin_port = htons(port);
 | 
				
			||||||
 | 
						serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
 | 
				
			||||||
 | 
						if(0 > bind(serverFd, (void *)&serverAddr, sizeof(serverAddr)))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("绑定失败!\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(0 > listen(serverFd, 1024))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							printf("监听失败!\n");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    return serverFd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// receive file's data
 | 
				
			||||||
 | 
					void* UpLoadServer(void * args){ 
 | 
				
			||||||
 | 
					    int clientFd = *(int *) args;
 | 
				
			||||||
 | 
					    char buf[4096];
 | 
				
			||||||
 | 
					    int ret = recv(clientFd,buf,4096,0);
 | 
				
			||||||
 | 
					    printf("ret=%d,errno=%d\n",ret,errno);
 | 
				
			||||||
 | 
					    FILE * file = fopen(data.fileName,"wb");
 | 
				
			||||||
 | 
					    fwrite(buf,4096,1,file);
 | 
				
			||||||
 | 
					    fclose(file);
 | 
				
			||||||
 | 
					    printf("upload complete for client: clientFd=%d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					    // notify for file download complete
 | 
				
			||||||
 | 
					    sem_post(&data.isDone);
 | 
				
			||||||
 | 
					    close(clientFd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//  send file's data
 | 
				
			||||||
 | 
					void* DownLoadServer(void * args){ 
 | 
				
			||||||
 | 
					    int clientFd = *(int *) args;
 | 
				
			||||||
 | 
					    char buf[4096];
 | 
				
			||||||
 | 
					    FILE * file = fopen(data.fileName,"rb");
 | 
				
			||||||
 | 
					    fread(buf,4096,1,file);
 | 
				
			||||||
 | 
					    send(clientFd,buf,sizeof(buf),0);
 | 
				
			||||||
 | 
					    fclose(file);
 | 
				
			||||||
 | 
					    printf("download complete for client: clientFd=%d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					    // notify for file download complete
 | 
				
			||||||
 | 
					    sem_post(&data.isDone);
 | 
				
			||||||
 | 
					    close(clientFd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// accept a client and new a thread for downlaod/upload
 | 
				
			||||||
 | 
					void* DataServer(void * args){
 | 
				
			||||||
 | 
					    dataServerFd = CreateServer(dataPort,1);
 | 
				
			||||||
 | 
					    while(1){
 | 
				
			||||||
 | 
					        // wait for a filename
 | 
				
			||||||
 | 
					        sem_wait(&data.isReady);
 | 
				
			||||||
 | 
					        struct sockaddr_in clientAdrr = {0};
 | 
				
			||||||
 | 
					        int socketLen = sizeof(clientAdrr);
 | 
				
			||||||
 | 
					        int clientFd = accept(dataServerFd,(struct sockaddr *)&clientAdrr,&socketLen);
 | 
				
			||||||
 | 
					        pthread_t thread;
 | 
				
			||||||
 | 
					        if(data.type == 0){ // download
 | 
				
			||||||
 | 
					            printf("accept a client for file download: clientFd=%d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					            pthread_create(&thread,NULL,&DownLoadServer,&clientFd);
 | 
				
			||||||
 | 
					        }else if(data.type == 1){ // upload
 | 
				
			||||||
 | 
					            printf("accept a client for file upload: clientFd=%d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					            pthread_create(&thread,NULL,&UpLoadServer,&clientFd);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // release lock
 | 
				
			||||||
 | 
					        sem_post(&mutex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// deal with order requests
 | 
				
			||||||
 | 
					void* OrderServer(void * args){
 | 
				
			||||||
 | 
					    int clientFd = *(int *)args;
 | 
				
			||||||
 | 
					    printf("in OrderServer thread: tid=%ld\n",pthread_self());
 | 
				
			||||||
 | 
					    // order format: USER anonymous\r\n
 | 
				
			||||||
 | 
					    // response code format: 213 4096\r\n
 | 
				
			||||||
 | 
					    while(1){
 | 
				
			||||||
 | 
					        recv(clientFd,order,4,0);
 | 
				
			||||||
 | 
					        printf("order=%s,tid=%ld\n",order,pthread_self());
 | 
				
			||||||
 | 
					        if(strcmp(order,"USER") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            if(strcmp(param," anonymous") == 0){
 | 
				
			||||||
 | 
					                respMessage = "331 Please specify the password.\r\n";
 | 
				
			||||||
 | 
					                SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"PASS") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            if(strcmp(param," anonymous") == 0){
 | 
				
			||||||
 | 
					                respMessage = "230 Login successful.\r\n";
 | 
				
			||||||
 | 
					                SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					                printf("login successful in clientFd %d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"TYPE") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            if(strcmp(param," I") == 0){
 | 
				
			||||||
 | 
					                isBinary = 1;
 | 
				
			||||||
 | 
					                respMessage = "200 Switching to Binary mode.\r\n";
 | 
				
			||||||
 | 
					                SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"SIZE") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            respMessage = "213 4096\r\n";
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"PASV") == 0){
 | 
				
			||||||
 | 
					            sem_wait(&mutex); // 锁竞争
 | 
				
			||||||
 | 
					            sem_init(&data.isDone,0,0);
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            char buf[50];
 | 
				
			||||||
 | 
					            sprintf(buf,"227 Entering passive mode (8,140,53,225,%d,%d).\r\n",dataPort/256,dataPort%256);
 | 
				
			||||||
 | 
					            respMessage = buf;
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"RETR") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            sprintf(data.fileName,"./data/%s",param+2);
 | 
				
			||||||
 | 
					            data.type = 0;
 | 
				
			||||||
 | 
					            // notify the thread of waiting fileName
 | 
				
			||||||
 | 
					            sem_post(&data.isReady);
 | 
				
			||||||
 | 
					            char buf[70];
 | 
				
			||||||
 | 
					            sprintf(buf,"150 Opening Binary mode data connection for %s (4096 bytes).\r\n",param+1);
 | 
				
			||||||
 | 
					            respMessage = buf;
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					            // wait for download complete
 | 
				
			||||||
 | 
					            printf("wait for download complete,tid=%ld\n",pthread_self());
 | 
				
			||||||
 | 
					            sem_wait(&data.isDone);
 | 
				
			||||||
 | 
					            respMessage = "226 Transfer complete.\r\n";
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					        }else if(strcmp(order,"STOR") == 0){
 | 
				
			||||||
 | 
					            RecvData(clientFd,param);
 | 
				
			||||||
 | 
					            sprintf(data.fileName,"./out/%s",param+1);
 | 
				
			||||||
 | 
					            data.type = 1;
 | 
				
			||||||
 | 
					            // notify the thread of waiting fileName
 | 
				
			||||||
 | 
					            sem_post(&data.isReady);
 | 
				
			||||||
 | 
					            char buf[70];
 | 
				
			||||||
 | 
					            sprintf(buf,"150 Opening Binary mode data connection for %s (4096 bytes).\r\n",param+1);
 | 
				
			||||||
 | 
					            respMessage = buf;
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					            // wait for upload complete
 | 
				
			||||||
 | 
					            printf("wait for upload complete,tid=%ld\n",pthread_self());
 | 
				
			||||||
 | 
					            sem_wait(&data.isDone);
 | 
				
			||||||
 | 
					            respMessage = "226 Transfer complete.\r\n";
 | 
				
			||||||
 | 
					            SendMessage(clientFd,respMessage);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(strcmp(order,"QUIT") == 0){
 | 
				
			||||||
 | 
					            printf("close clientFd=%d,tid=%ld\n",clientFd,pthread_self());
 | 
				
			||||||
 | 
					            close(clientFd);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(){
 | 
				
			||||||
 | 
					    serverFd = CreateServer(port,0);
 | 
				
			||||||
 | 
					    sem_init(&data.isReady,0,0);
 | 
				
			||||||
 | 
					    sem_init(&mutex,0,1);
 | 
				
			||||||
 | 
					    pthread_t thread;
 | 
				
			||||||
 | 
					    pthread_create(&thread,NULL,&DataServer,NULL);
 | 
				
			||||||
 | 
					    int clientFds[THREAD_NUM];
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    while(1){
 | 
				
			||||||
 | 
					        struct sockaddr_in clientAdrr = {0}; 
 | 
				
			||||||
 | 
					        int socketLen = sizeof(clientAdrr);
 | 
				
			||||||
 | 
					        clientFds[i] = accept(serverFd,(struct sockaddr *)&clientAdrr,&socketLen);
 | 
				
			||||||
 | 
					        printf("accept a client:fd=%d\n",clientFds[i]);
 | 
				
			||||||
 | 
					        respMessage = "220 (myFtpServer 1.0)\r\n";
 | 
				
			||||||
 | 
					        SendMessage(clientFds[i],respMessage);
 | 
				
			||||||
 | 
					        printf("send welcome message successfully.\n");
 | 
				
			||||||
 | 
					        pthread_t thread;
 | 
				
			||||||
 | 
					        pthread_create(&thread,NULL,&OrderServer,&clientFds[i]);
 | 
				
			||||||
 | 
					        i++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 97 KiB  | 
| 
		 After Width: | Height: | Size: 201 KiB  | 
| 
		 After Width: | Height: | Size: 218 KiB  | 
| 
		 After Width: | Height: | Size: 165 KiB  | 
| 
		 After Width: | Height: | Size: 264 KiB  | 
| 
		 After Width: | Height: | Size: 207 KiB  | 
| 
		 After Width: | Height: | Size: 350 KiB  | 
| 
		 After Width: | Height: | Size: 172 KiB  | 
| 
		 After Width: | Height: | Size: 247 KiB  | 
| 
		 After Width: | Height: | Size: 336 KiB  | 
| 
		 After Width: | Height: | Size: 269 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
| 
		 After Width: | Height: | Size: 473 KiB  | 
| 
		 After Width: | Height: | Size: 331 KiB  | 
| 
		 After Width: | Height: | Size: 228 KiB  | 
| 
		 After Width: | Height: | Size: 208 KiB  | 
| 
		 After Width: | Height: | Size: 222 KiB  | 
| 
		 After Width: | Height: | Size: 199 KiB  | 
| 
		 After Width: | Height: | Size: 268 KiB  | 
| 
		 After Width: | Height: | Size: 250 KiB  | 
| 
		 After Width: | Height: | Size: 174 KiB  | 
| 
		 After Width: | Height: | Size: 193 KiB  | 
| 
		 After Width: | Height: | Size: 48 KiB  | 
| 
		 After Width: | Height: | Size: 346 KiB  | 
| 
		 After Width: | Height: | Size: 412 KiB  | 
| 
		 After Width: | Height: | Size: 189 KiB  | 
| 
		 After Width: | Height: | Size: 220 KiB  | 
| 
		 After Width: | Height: | Size: 52 KiB  | 
| 
		 After Width: | Height: | Size: 59 KiB  | 
| 
		 After Width: | Height: | Size: 56 KiB  | 
| 
		 After Width: | Height: | Size: 56 KiB  | 
| 
		 After Width: | Height: | Size: 50 KiB  | 
| 
		 After Width: | Height: | Size: 61 KiB  | 
| 
		 After Width: | Height: | Size: 31 KiB  | 
| 
		 After Width: | Height: | Size: 61 KiB  | 
| 
		 After Width: | Height: | Size: 77 KiB  | 
| 
		 After Width: | Height: | Size: 84 KiB  | 
| 
		 After Width: | Height: | Size: 19 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
| 
		 After Width: | Height: | Size: 114 KiB  | 
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 235 KiB  | 
| 
		 After Width: | Height: | Size: 211 KiB  | 
| 
		 After Width: | Height: | Size: 230 KiB  | 
| 
		 After Width: | Height: | Size: 55 KiB  | 
| 
						 | 
					@ -0,0 +1,93 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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:   a ftpClient test sample
 | 
				
			||||||
 | 
					* @version: 1.0
 | 
				
			||||||
 | 
					* @author:  bdislab_final
 | 
				
			||||||
 | 
					* @date:    2023/9/16
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_ftpclient_final.h"
 | 
				
			||||||
 | 
					#include "ftp_client/ftp_client.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <transform.h>
 | 
				
			||||||
 | 
					#include <pthread.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int threadIDs[THREAD_NUM];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*one client upLoad a file of 4K*/
 | 
				
			||||||
 | 
					void* UpLoad(void* arg){
 | 
				
			||||||
 | 
					    int *pThreadID = (int*)arg;
 | 
				
			||||||
 | 
					    printf("in thread:tid=%ld\n", pthread_self());
 | 
				
			||||||
 | 
					    FtpInitCmd(*pThreadID);
 | 
				
			||||||
 | 
					    int ret = FtpLogin(*pThreadID,"8.140.53.225", 9992, "anonymous", "anonymous");
 | 
				
			||||||
 | 
					    int size = 4096;
 | 
				
			||||||
 | 
					    char buf[size];
 | 
				
			||||||
 | 
					    char fileName[20];
 | 
				
			||||||
 | 
					    sprintf(fileName,"file%d",*pThreadID);
 | 
				
			||||||
 | 
					    for(int i = 0;i < size;++i){
 | 
				
			||||||
 | 
					        buf[i] = '0';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    FtpInitData(*pThreadID);  // data socket 每次下载都要重新创建,下载完都要关闭
 | 
				
			||||||
 | 
					    ret = FtpUpload(*pThreadID,fileName,buf,size);
 | 
				
			||||||
 | 
					    FtpQuit(*pThreadID);
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*one client downLoad a file of 4K*/
 | 
				
			||||||
 | 
					void* DownLoad(void* arg){
 | 
				
			||||||
 | 
					    int *pThreadID = (int*)arg;
 | 
				
			||||||
 | 
					    printf("in thread:tid=%ld\n", pthread_self());
 | 
				
			||||||
 | 
					    FtpInitCmd(*pThreadID);
 | 
				
			||||||
 | 
					    int ret = FtpLogin(*pThreadID,"8.140.53.225", 9992, "anonymous", "anonymous");
 | 
				
			||||||
 | 
					    int size;
 | 
				
			||||||
 | 
					    char *buf;
 | 
				
			||||||
 | 
					    char fileName[20] = "/file1"; 
 | 
				
			||||||
 | 
					    size = FtpFileSize(*pThreadID,fileName);
 | 
				
			||||||
 | 
					    buf = malloc(size);
 | 
				
			||||||
 | 
					    FtpInitData(*pThreadID);  // data socket 每次下载都要重新创建,下载完都要关闭
 | 
				
			||||||
 | 
					    ret = FtpDownload(*pThreadID,fileName, buf, size);
 | 
				
			||||||
 | 
					    free(buf);
 | 
				
			||||||
 | 
					    FtpQuit(*pThreadID);
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* test for 10 ftp client */
 | 
				
			||||||
 | 
					void TestFtpClient(int argc, char* argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int options = atoi(argv[1]);
 | 
				
			||||||
 | 
					    int n = atoi(argv[2]);
 | 
				
			||||||
 | 
					    pthread_t threads[THREAD_NUM];
 | 
				
			||||||
 | 
					    for(int i = 0;i < n;++i){
 | 
				
			||||||
 | 
					        threadIDs[i] = i;
 | 
				
			||||||
 | 
					        if(options == 1){ // 全部都是下载
 | 
				
			||||||
 | 
					            pthread_create(&threads[i],NULL,&DownLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					        }else if(options == 2){ // 全部都是上传
 | 
				
			||||||
 | 
					            pthread_create(&threads[i],NULL,&UpLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					        }else if(options == 3){  // 随机下载/上传
 | 
				
			||||||
 | 
					            int r = rand()%2;
 | 
				
			||||||
 | 
					            if(r == 0){
 | 
				
			||||||
 | 
					                printf("===============download===============\n");
 | 
				
			||||||
 | 
					                pthread_create(&threads[i],NULL,&DownLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					            }else{
 | 
				
			||||||
 | 
					                printf("===============upload===============\n");
 | 
				
			||||||
 | 
					                pthread_create(&threads[i],NULL,&UpLoad,&threadIDs[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					PRIV_SHELL_CMD_FUNCTION(TestFtpClient, a ftpClient test sample, PRIV_SHELL_CMD_MAIN_ATTR);
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright (c) 2020 AIIT XUOS Lab
 | 
				
			||||||
 | 
					* 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 a ftpClient test sample
 | 
				
			||||||
 | 
					 * @version 1.0
 | 
				
			||||||
 | 
					 * @author bdislab_final
 | 
				
			||||||
 | 
					 * @date 2023/9/16
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TEST_FTPCLIENT_H
 | 
				
			||||||
 | 
					#define TEST_FTPCLIENT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					/*one client upLoad a file of 4K*/
 | 
				
			||||||
 | 
					void* UpLoad(void* arg);
 | 
				
			||||||
 | 
					/*one client downLoad 10 files of 4K*/
 | 
				
			||||||
 | 
					void* DownLoad(void* arg);
 | 
				
			||||||
 | 
					/* test for ftp client */
 | 
				
			||||||
 | 
					void TestFtpClient(int argc, char* argv[]);
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||