diff --git a/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.c b/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.c index 805768f1c..ff567dfc1 100644 --- a/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.c +++ b/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.c @@ -10,6 +10,18 @@ #include "lwip/sockets.h" #include "lwip/netdb.h" +static pthread_mutex_t *mutex; + +int ftp_init() +{ + return PrivMutexCreate(mutex, NULL); +} + +int ftp_close() +{ + return PrivMutexDelete(mutex); +} + /** * @description: Send a cmd to FTP server * @param socket - Control socket @@ -19,7 +31,7 @@ * @param other - Store output parameter if needed * @return 0: success; others: failure */ -static int ftp_cmd(int socket, int wait_time, int cmd, char *param, int *other) +int ftp_cmd(int socket, int wait_time, int cmd, char *param, int *other) { fd_set readset; struct timeval timeout; @@ -124,8 +136,8 @@ static int ftp_cmd(int socket, int wait_time, int cmd, char *param, int *other) /* Waiting for server response */ if (select(socket + 1, &readset, NULL, NULL, &timeout) <= 0) { - LOG_I("select the socket timeout!\n"); - return -1; + LOG_I("select the socket timeout!\n"); + return -1; } /* Wait and receive the packet back from the server. */ @@ -141,7 +153,7 @@ static int ftp_cmd(int socket, int wait_time, int cmd, char *param, int *other) ++i; } buff[i + 1] = '\0'; - LOG_I("Recv:%s\n", buff); + // LOG_I("Recv:%s\n", buff); /* Identify if the status code is correct according to cmd */ switch (cmd) @@ -308,8 +320,9 @@ static int ftp_cmd(int socket, int wait_time, int cmd, char *param, int *other) * @param getlen - Actual length of data received * @return 0: success; others: failure */ -static int ftp_downloaddata(int socket, int wait_time, char *buf, int bufsize, int *getlen) +int ftp_downloaddata(int socket, int wait_time, char *buf, int bufsize, int *getlen) { + memset(buf, 0, bufsize); fd_set readset; struct timeval timeout; int len = 0; @@ -345,7 +358,7 @@ static int ftp_downloaddata(int socket, int wait_time, char *buf, int bufsize, i * @param getlen - Actual length of data sended * @return 0: success; others: failure */ -static int ftp_uploaddata(int socket, char *buf, int bufsize, int *getlen) +int ftp_uploaddata(int socket, char *buf, int bufsize, int *getlen) { int len = 0; @@ -451,13 +464,12 @@ __exit: int ftp_downloadfile(ftp_client *ftp, char *file_name) { int ret = 0, fd = 0; - struct addrinfo hints, *result = NULL, *cur = NULL; int getlen = 0; int file_pos = 0; int port = 0; int file_size = 0; - char filebuf[128] = {0}; + char filebuf[256] = {0}; /* Enter the pasv mode */ if (ftp_cmd(ftp->control_socket, 10000, PASV, NULL, &port) != 0) { @@ -466,32 +478,19 @@ int ftp_downloadfile(ftp_client *ftp, char *file_name) } /* 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; + fd = socket(AF_INET, SOCK_STREAM, 0); + int bufsize = 1024 * 1024; + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); sprintf(ftp->data_port, "%d", port); + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = inet_addr(ftp->server_ip); - /* Do name resolution with both IPv6 and IPv4 */ - if (getaddrinfo(ftp->server_ip, ftp->data_port, &hints, &result) != 0) { - goto __exit; - } - - for (cur = result; 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(result); + if (connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == 0) + ftp->data_socket = fd; if(ftp->data_socket < 0) { @@ -505,6 +504,30 @@ int ftp_downloadfile(ftp_client *ftp, char *file_name) goto __exit; } + char name[64]; + sprintf(name, "/%s", file_name); + int f = PrivOpen(name, O_RDWR|O_CREAT); + /* Read the file */ + while(1) { + if (ftp_downloaddata(ftp->data_socket, 10000, filebuf, 128, &getlen) == 0) { + if (getlen) { + PrivMutexObtain(mutex); + ret = PrivWrite(f, filebuf, strlen(filebuf)); + PrivMutexAbandon(mutex); + if (ret < 0) { + break; + } + } else { + break; + } + } else { + break; + } + file_pos = file_pos + getlen; + } + printf("Total length: %d\n", file_pos); // Compare the size of the file previously returned by the server + PrivClose(f); + /* Waite the download file finish */ if (ftp_cmd(ftp->control_socket, 10000, FINISH, NULL, NULL) != 0) { ret = -1; @@ -512,30 +535,6 @@ int ftp_downloadfile(ftp_client *ftp, char *file_name) ret = 0; } - char name[64]; - sprintf(name, "/%s", file_name); - int f = PrivOpen(name, O_RDWR|O_CREAT); - /* Read the file */ - while(file_size > file_pos) { - if (ftp_downloaddata(ftp->data_socket, 10000, filebuf, 128, &getlen) == 0) { - if (getlen) { - ret = PrivWrite(f, filebuf, strlen(filebuf)); - if (ret < 0) { - printf("write failed,error:%d\n", ret); - goto __exit; - } - } else { - ret = -1; - goto __exit; - } - } else { - ret = -1; - goto __exit; - } - file_pos = file_pos + getlen; - } - printf("Total length: %d\n", file_pos); // Compare the size of the file previously returned by the server - PrivClose(f); __exit: if(ftp->data_socket >= 0) { @@ -569,32 +568,19 @@ int ftp_uploadfile(ftp_client *ftp, char *file_name) } /* 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, &result) != 0) { - goto __exit; - } + fd = socket(AF_INET, SOCK_STREAM, 0); + int bufsize = 1024 * 1024; + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); - for (cur = result; cur != NULL; cur = cur->ai_next) { - fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); - if (fd < 0) { - continue; - } + sprintf(ftp->data_port, "%d", port); + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = inet_addr(ftp->server_ip); - if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) { - ftp->data_socket = fd; - break; - } - closesocket(fd); - - } - freeaddrinfo(result); + if (connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == 0) + ftp->data_socket = fd; if(ftp->data_socket < 0) { @@ -619,28 +605,21 @@ int ftp_uploadfile(ftp_client *ftp, char *file_name) while((ret = PrivRead(f, filebuf, 128)) != 0) { if (ret < 0) { printf("read failed.\n"); - goto __exit; + break; } if (ftp_uploaddata(ftp->data_socket, filebuf, ret, &getlen) == 0) { if (!getlen) { ret = -1; - goto __exit; + break; } } else { ret = -1; - goto __exit; + break; } - file_pos = file_pos + getlen; + file_pos += getlen; } printf("Total length: %d\n", file_pos); - /* Uploading a file requires the client to actively close the socket. */ - if(ftp->data_socket >= 0) - { - closesocket(ftp->data_socket); - ftp->data_socket = -1; - } - /* Waite the upload file finish */ if (ftp_cmd(ftp->control_socket, 10000, FINISH, NULL, NULL) != 0) { ret = -1; diff --git a/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.h b/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.h index 83663f02d..c58e1ac03 100644 --- a/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.h +++ b/APP_Framework/Applications/app_test/test_ftpclient/ftp_client/ftp_client.h @@ -34,6 +34,8 @@ typedef struct ftp_client_struct int data_socket; }ftp_client; +int ftp_init(); +int ftp_close(); ftp_client *ftp_login(char *addr, char *username, char *password); int ftp_downloadfile(ftp_client *ftp, char *file_name); int ftp_uploadfile(ftp_client *ftp, char *file_name); diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/README.md b/APP_Framework/Applications/app_test/test_ftpclient_final/README.md index 364143051..f44f0ea54 100644 --- a/APP_Framework/Applications/app_test/test_ftpclient_final/README.md +++ b/APP_Framework/Applications/app_test/test_ftpclient_final/README.md @@ -36,6 +36,8 @@ typedef struct ftp_client_struct ### FTP server +FTP server 的代码托管在 https://github.com/JasenChao/ftp_server.git 。 + FTP server设计为: ```c @@ -78,9 +80,7 @@ typedef struct _ftp_server 3. 将开发板与路由器连接,根据实际情况修改代码中的网卡配置部分,使得开发板可以上网。 -4. `TestFtpClientFinal` 命令需要一个参数,参数可选 `upload` 和 `download`,分别会启动 10 个线程,进行文件名拼接,然后登陆到 FTP server,进行对应文件的上传/下载。注意需要将测试程序中 `ftp_login` 的 server ip、用户名以及密码替换为实际情况的内容。 - -5. 关闭 FTP client。 +4. `TestFtpClientFinal` 命令需要一个参数,参数可选 `init`、`close`、`upload`、`download`,分别会初始化和关闭FTP,启动 10 个线程,进行文件名拼接,然后登陆到 FTP server,进行对应文件的上传/下载。注意需要将测试程序中 `ftp_login` 的 server ip、用户名以及密码替换为实际情况的内容。 ## 4. 运行结果(需结合运行测试截图按步骤说明) @@ -96,28 +96,30 @@ typedef struct _ftp_server ![fig2](fig2.png) -5. 执行 `TestFtpClientFinal download` 命令,10 个线程并发创建 10 个 client 下载对应的 10 个文件,可以看到下载过程是并发进行的。 +5. 执行 `TestFtpClientFinal init` 命令,初始化网卡和互斥量。 ![fig3](fig3.png) + +6. 执行 `TestFtpClientFinal download` 命令,10 个线程并发创建 10 个 client 下载对应的 10 个文件,可以看到下载过程是并发进行的。 + ![fig4](fig4.png) ![fig5](fig5.png) + +7. 执行 `ls` 命令,看到文件全部下载成功,大小与 server 一致。 + ![fig6](fig6.png) -6. 执行 `ls` 命令,看到文件全部下载成功,大小与 server 一致。 - - ![fig7](fig7.png) - -7. 在 server 端执行 `rm file_*` 命令,删除服务器端的测试文件。 +8. 在 server 端执行 `rm file_*` 命令,删除服务器端的测试文件。 8. 执行 `TestFtpClientFinal upload` 命令,10 个线程并发创建 10 个 client 上传刚刚下载的 10 个文件,可以看到上传过程是并发进行的。 + ![fig7](fig7.png) ![fig8](fig8.png) ![fig9](fig9.png) ![fig10](fig10.png) + +9. 在 server 端执行 `ll --block-size=1` 命令,可以看到文件全部重新上传,时间与之前删除的相比有变化,大小与之前一致,通过打开比对可以发现内容也一致。 + ![fig11](fig11.png) -9. 在 server 端执行 `ll --block-size=1` 命令,可以看到文件全部重新上传,大小与之前一致。 - - ![fig12](fig12.png) - 10. 测试结束。 \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig0.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig0.png index 0ad445a9e..cb406a042 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig0.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig0.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig1.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig1.png index cc8172c0c..1acd11e7c 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig1.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig1.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig10.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig10.png deleted file mode 100644 index b2f145fa9..000000000 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig10.png and /dev/null differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig11.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig11.png deleted file mode 100644 index a5d402eed..000000000 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig11.png and /dev/null differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig12.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig12.png deleted file mode 100644 index 0af484487..000000000 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig12.png and /dev/null differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig2.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig2.png index 52c9de348..2d87002ce 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig2.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig2.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig3.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig3.png index b4ca8739c..042cfed71 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig3.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig3.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig4.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig4.png index 00164c5ee..99cb2ad39 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig4.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig4.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig5.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig5.png index bca61e85a..e875d10e1 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig5.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig5.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig6.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig6.png index 4aa7c3780..29e2ade17 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig6.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig6.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig7.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig7.png index 10f5c1702..99183df90 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig7.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig7.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig8.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig8.png index b9668a777..97ecc2b1b 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig8.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig8.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/fig9.png b/APP_Framework/Applications/app_test/test_ftpclient_final/fig9.png index 37461ac52..e40c5ee75 100644 Binary files a/APP_Framework/Applications/app_test/test_ftpclient_final/fig9.png and b/APP_Framework/Applications/app_test/test_ftpclient_final/fig9.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient_final.c b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient_final.c index bc348b51b..7c6836d00 100644 --- a/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient_final.c +++ b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient_final.c @@ -42,14 +42,14 @@ void TestFtpClientFinal(int argc, char *argv[]) { pthread_attr_t attr; attr.schedparam.sched_priority = 22; - attr.stacksize = 4096; + attr.stacksize = 2048; memset(f, 0, sizeof(f)); /* Initialize the network IP */ char self_ipaddr[] = {192, 168, 130, 77}; char self_netmask[] = {255, 255, 254, 0}; - char self_gwaddr[] = {192, 168, 130, 1}; + char self_gwaddr[] = {192, 168, 130, 78}; lwip_config_tcp(0, self_ipaddr, self_netmask, self_gwaddr); if (strcmp(argv[1], "upload") == 0) { @@ -64,6 +64,10 @@ void TestFtpClientFinal(int argc, char *argv[]) { pthread_t down; PrivTaskCreate(&down, &attr, &downloadfunc, &i); } + } else if (strcmp(argv[1], "init") == 0) { + ftp_init(); + } else if (strcmp(argv[1], "close") == 0) { + ftp_close(); } } PRIV_SHELL_CMD_FUNCTION(TestFtpClientFinal, 2023 open source contest final 1 st issue3, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file