add concurrent upload function
|
@ -3,8 +3,8 @@
|
||||||
## 1. 简介
|
## 1. 简介
|
||||||
本项目是基于赛事提供的云服务器,实现FTP协议的Server功能,其功能支持至少10个Client端并发向Server端传输4KB大小的文件,
|
本项目是基于赛事提供的云服务器,实现FTP协议的Server功能,其功能支持至少10个Client端并发向Server端传输4KB大小的文件,
|
||||||
支持Server端并发地向至少10个Client端传输4KB大小的文件。
|
支持Server端并发地向至少10个Client端传输4KB大小的文件。
|
||||||
test_ftpclient_final.h声明了多个客户端并发下载文件的测试函数
|
test_ftpclient_final.h声明了多个客户端并发下载文件、并发上传文件的测试函数
|
||||||
test_ftpclient_final.c实现了多个客户端并发下载文件的测试函数
|
test_ftpclient_final.c实现了多个客户端并发下载文件、并发上传文件的测试函数
|
||||||
ftp_client文件夹定义了ftp_client的相关类库其中my_socket.h,my_socket.c定义了socket抽象层,并基于
|
ftp_client文件夹定义了ftp_client的相关类库其中my_socket.h,my_socket.c定义了socket抽象层,并基于
|
||||||
Lwip实现了该抽象层,ftp_client.h,ftp_client.c实现了ftp登录,获取文件大小,下载文件等功能
|
Lwip实现了该抽象层,ftp_client.h,ftp_client.c实现了ftp登录,获取文件大小,下载文件等功能
|
||||||
注意:在赛事提供的云服务器/root/yanglongFTP上有对应服务器代码 ./server运行服务器
|
注意:在赛事提供的云服务器/root/yanglongFTP上有对应服务器代码 ./server运行服务器
|
||||||
|
@ -36,15 +36,21 @@ struct Data{ // 用于线程间通信
|
||||||
```
|
```
|
||||||
## 3. 测试程序说明
|
## 3. 测试程序说明
|
||||||
- test_ftpclient_final.c用于测试多个客户端并发下载文件
|
- test_ftpclient_final.c用于测试多个客户端并发下载文件
|
||||||
通过多线程模拟多个客户端并发访问服务器
|
通过多线程模拟多个客户端并发访问服务器,通过 TestFtpClient options threads进行测试
|
||||||
|
其中options=1表示下载options=2表示上传,threads表示线程数/模拟的并发客户端数目
|
||||||
```c
|
```c
|
||||||
/* test for 10 ftp client */
|
/* test for 10 ftp client */
|
||||||
void TestFtpClient(int argc, char* argv[])
|
void TestFtpClient(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int n = atoi(argv[1]);
|
int options = atoi(argv[1]);
|
||||||
|
int n = atoi(argv[2]);
|
||||||
for(int i = 0;i < n;++i){
|
for(int i = 0;i < n;++i){
|
||||||
threadIDs[i] = i;
|
threadIDs[i] = i;
|
||||||
pthread_create(NULL,NULL,&downLoad,&threadIDs[i]);
|
if(options == 1){ // for DownLoad
|
||||||
|
pthread_create(NULL,NULL,&DownLoad,&threadIDs[i]);
|
||||||
|
}else if(options == 2){ // for upLoad
|
||||||
|
pthread_create(NULL,NULL,&UpLoad,&threadIDs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +70,7 @@ PRIV_SHELL_CMD_FUNCTION(TestFtpClient, a ftpClient test sample, PRIV_SHELL_CMD_M
|
||||||

|

|
||||||
5. 通过./server在云服务器运行FTP服务器
|
5. 通过./server在云服务器运行FTP服务器
|
||||||

|

|
||||||
6. 运行TestFtpClient 10,模拟10个客户端并发下载文件
|
6. 运行TestFtpClient 1 10,模拟10个客户端并发下载文件
|
||||||
- 客户端日志
|
- 客户端日志
|
||||||

|

|
||||||

|

|
||||||
|
@ -81,4 +87,20 @@ PRIV_SHELL_CMD_FUNCTION(TestFtpClient, a ftpClient test sample, PRIV_SHELL_CMD_M
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
7. 运行TestFtpClient 2 10,模拟10个客户端并发上传文件
|
||||||
|
- 客户端日志
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
- 服务器日志
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
- 上传结果
|
||||||
|

|
|
@ -89,7 +89,53 @@ static int FtpEnterPasv(int threadID,char *ipaddr, int *port)
|
||||||
*port = pa * 256 + pb;
|
*port = pa * 256 + pb;
|
||||||
return 1;
|
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 FtpDownload(int threadID,char *name, void *buf, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -41,4 +41,6 @@ int FtpFileSize(int threadID,char *name);
|
||||||
/* ftp download file*/
|
/* ftp download file*/
|
||||||
int FtpDownload(int threadID,char *name, void *buf, int len);
|
int FtpDownload(int threadID,char *name, void *buf, int len);
|
||||||
|
|
||||||
|
/*ftp upload*/
|
||||||
|
int FtpUpload(int threadID,char *name, void *buf, int len);
|
||||||
#endif
|
#endif
|
||||||
|
|
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: 346 KiB |
After Width: | Height: | Size: 412 KiB |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 220 KiB |
|
@ -28,11 +28,27 @@
|
||||||
|
|
||||||
int threadIDs[THREAD_NUM];
|
int threadIDs[THREAD_NUM];
|
||||||
|
|
||||||
void delay(int n){
|
/*one client upLoad a file of 4K*/
|
||||||
for(int i = 0;i < n;++i);
|
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*/
|
/*one client downLoad a file of 4K*/
|
||||||
void* downLoad(void* arg){
|
void* DownLoad(void* arg){
|
||||||
int *pThreadID = (int*)arg;
|
int *pThreadID = (int*)arg;
|
||||||
printf("in thread:tid=%ld\n", pthread_self());
|
printf("in thread:tid=%ld\n", pthread_self());
|
||||||
FtpInitCmd(*pThreadID);
|
FtpInitCmd(*pThreadID);
|
||||||
|
@ -43,7 +59,6 @@ void* downLoad(void* arg){
|
||||||
size = FtpFileSize(*pThreadID,fileName);
|
size = FtpFileSize(*pThreadID,fileName);
|
||||||
buf = malloc(size);
|
buf = malloc(size);
|
||||||
FtpInitData(*pThreadID); // data socket 每次下载都要重新创建,下载完都要关闭
|
FtpInitData(*pThreadID); // data socket 每次下载都要重新创建,下载完都要关闭
|
||||||
delay(1000);
|
|
||||||
ret = FtpDownload(*pThreadID,fileName, buf, size);
|
ret = FtpDownload(*pThreadID,fileName, buf, size);
|
||||||
free(buf);
|
free(buf);
|
||||||
FtpQuit(*pThreadID);
|
FtpQuit(*pThreadID);
|
||||||
|
@ -53,10 +68,15 @@ void* downLoad(void* arg){
|
||||||
/* test for 10 ftp client */
|
/* test for 10 ftp client */
|
||||||
void TestFtpClient(int argc, char* argv[])
|
void TestFtpClient(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int n = atoi(argv[1]);
|
int options = atoi(argv[1]);
|
||||||
|
int n = atoi(argv[2]);
|
||||||
for(int i = 0;i < n;++i){
|
for(int i = 0;i < n;++i){
|
||||||
threadIDs[i] = i;
|
threadIDs[i] = i;
|
||||||
pthread_create(NULL,NULL,&downLoad,&threadIDs[i]);
|
if(options == 1){ // for DownLoad
|
||||||
|
pthread_create(NULL,NULL,&DownLoad,&threadIDs[i]);
|
||||||
|
}else if(options == 2){ // for upLoad
|
||||||
|
pthread_create(NULL,NULL,&UpLoad,&threadIDs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/*one client upLoad a file of 4K*/
|
||||||
|
void* UpLoad(void* arg);
|
||||||
/*one client downLoad 10 files of 4K*/
|
/*one client downLoad 10 files of 4K*/
|
||||||
void* downLoad(void* arg);
|
void* DownLoad(void* arg);
|
||||||
/* test for ftp client */
|
/* test for ftp client */
|
||||||
void TestFtpClient(int argc, char* argv[]);
|
void TestFtpClient(int argc, char* argv[]);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|