update server readme

This commit is contained in:
ambrumf 2023-10-20 02:49:56 +08:00
parent 4fb42af1a0
commit f6c51cb88c
15 changed files with 128 additions and 35 deletions

View File

@ -0,0 +1,80 @@
# 基于赛事提供的云服务器的Server服务器
## 1. 简介
利用c语言实现了ftp服务器支持至少10个Client端并发向Server端传输4KB大小的文件支持Server端并发地向至少10个Client端传输4KB大小的文件
## 2. 数据结构设计说明
user类用于持久化用户名和密码
```c
struct User {
char username[50];
char password[50];
};
```
LoginStatus类用于持久化用户的登录信息
```c
struct LoginStatus {
char *addr;
char username[50];
char password[50];
int login_status;
};
```
服务端包含以下函数:
```c
void StartNewConnection(int data_fd,struct sockaddr_in client_addr);//创建新连接
void GetFullAddress(char* client_id, char* client_ip, int client_port);//根据客户端ip地址和端口号生成完整地址
int CheckPassword(int it);//验证用户名与密码是否匹配
void *CreateDataSockt(void *arg);//创建新数据连接
char* GetRespond(char* buf, int it, int* ret, int cmd_fd);//根据输入的指令获取相应数据
void *RecvSend(void *arg);//接收请求发送回应
int Init();//初始化
```
## 3. 测试程序说明
测试在本地运行10个客户端并行下载服务器的4kb文件10个客户端向服务器并行上传10个4kb的文件。
## 4. 运行结果(##需结合运行测试截图按步骤说明##
![image](img/01.png)
![image](img/02.png)
打开menuconfig之后将Using LwIP by ethernet开启(y)Using SD CARD device开启(y),Config test ftp client 开启y保存后退出
![image](img/03.png)
编译XiZi-edu-arm32.elf成功
![image](img/04.png)
启动HDSC烧录XiZi-edu-arm32.bin文件至开发板
![image](img/05.png)
将开发板与路由器连接配置开发板ip地址子网掩码网关使得开发板能连接互联网
![image](img/06.png)
使用putty连接服务器(8.140.53.225)用户名:xiuos 密码:xiuos@123
![image](img/07.png)
cd wojiuguaji 进入文件夹
![image](img/07.png)
cd wojiuguaji 进入文件夹
![image](img/08.png)
gcc ftpserver.c -lpthread 编译服务端文件
![image](img/09.png)
./a.out 运行服务端文件
![image](img/10.png)
打开MobaXterm连接开发板
![image](img/11.png)
在MobaXterm输入DownloadTest测试10个客户端并发下载可以看到成功下载10个4KB的文件
![image](img/12.png)
在服务器终端输入Ctrl + C结束服务器进程等待一段时间后服务解除占用的端口后再次使用./a.out运行服务器程序
![image](img/13.png)
在MobaXterm输入UploadTest测试10个客户端并发上传可以看到成功上传10个4KB的文件

View File

@ -34,7 +34,7 @@
#define MAX_CONNECTION 100
#define UNLOGED_IN 0
#define LOGED_IN 1
int pasv_complete[200];
int off = 0;
int fd_map[200];
struct User {
@ -49,6 +49,8 @@ struct LoginStatus {
int login_status;
};
pthread_mutex_t mutex;
struct User users[MAX_USERS];
struct LoginStatus login_list[MAX_CONNECTION];
@ -61,13 +63,16 @@ void GetFullAddress(char* client_id, char* client_ip, int client_port) {
int CheckPassword(int it) {
for (int i = 0;i < MAX_USERS;i++) {
if (strcmp(login_list[it].username, users[i].username) == 0 && strcmp(login_list[it].password, users[i].password) == 0)return 1;
if (strcmp(login_list[it].username, users[i].username) == 0 && strcmp(login_list[it].password, users[i].password) == 0)
{
return 1;
}
}
return 0;
}
void *CreateDataSockt(void *arg) {
pthread_mutex_lock(&mutex);
int *data = arg;
int port = data[0];
int cmd_fd = data[1];
@ -82,9 +87,9 @@ void *CreateDataSockt(void *arg) {
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
int ret = bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
int ret = bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
pthread_mutex_unlock(&mutex);
if (ret < 0) {
printf("%d\n", ret);
printf("Failed to bind socket\n");
return NULL;
}
@ -95,22 +100,21 @@ void *CreateDataSockt(void *arg) {
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
int data_fd = accept(fd, (struct sockaddr *)&client_addr, &len);
int data_fd = accept(fd, (struct sockaddr*)&client_addr, &len);
fd_map[cmd_fd] = data_fd;
pasv_complete[data_fd] = 1;
}
close(fd);
return NULL;
}
char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
char * cmd = malloc(100);
char* GetRespond(char* buf, int it, int* ret, int cmd_fd) {
pthread_mutex_lock(&mutex);
char* cmd = malloc(100);
char * data = malloc(100);
char* respond = malloc(100);
//debug
printf("%s\n", buf);
sscanf(buf, "%s %s", cmd, data);
if(strcmp(cmd,"USER")==0){
login_list[it].login_status=LOGED_IN;
@ -131,14 +135,14 @@ char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
if (stat(data, &file_stat) == 0) {
int size = file_stat.st_size;
sprintf(respond, "213 %d", size);
sprintf(respond, "213 %d\n", size);
}
else sprintf(respond, "550 file not found");
else sprintf(respond, "550 file not found\n");
}
else if (strcmp(cmd, "PASV") == 0) {
off = (off + 1) % 15;
int port = 9980 + off;
sprintf(respond, "227 enter passive mode (8.140.53.225,%d,%d)", port / 256, port % 256);
sprintf(respond, "227 enter passive mode (8,140,53,225,%d,%d)\n", port / 256, port % 256);
pthread_t thread;
int arg[2];
arg[0] = port;
@ -147,7 +151,8 @@ char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
*ret = 227;
}
else if (strcmp(cmd, "RETR") == 0) {
char* dir=malloc(100);
while (pasv_complete[fd_map[cmd_fd]] == 0);
char* dir = malloc(100);
sprintf(dir, "/home/xiuos/wojiuguaji/%s", data);
FILE* file = fopen(dir, "rb");
if (file == NULL) {
@ -158,14 +163,16 @@ char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
char* start = "150 starting data transfer\n";
write(cmd_fd, start, strlen(start));
char* buff = (char*)malloc(file_size);
char* buff = (char*)malloc(file_size + 1);
memset(buff, sizeof(buff), 0);
fread(buff, 1, file_size, file);
int size = write(fd_map[cmd_fd], buff, strlen(buff));
int size = send(fd_map[cmd_fd], buff, strlen(buff), 0);
if (size < 0) {
perror("send error");
printf("failed to send message\n");
}
char* end = "226 Operation successfull";
char* end = "226 Operation successfull\n";
write(cmd_fd, end, strlen(end));
fclose(file);
@ -173,21 +180,25 @@ char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
free(dir);
}
else if (strcmp(cmd, "STOR") == 0) {
char* dir=malloc(100);
while (pasv_complete[fd_map[cmd_fd]] == 0);
char* dir = malloc(100);
sprintf(dir, "/home/xiuos/wojiuguaji/%s", data);
FILE* file = fopen(dir, "wb");
if (file == NULL) {
perror("file openfail");
sprintf(respond, "550 failed to open file\n");
}
char* start = "150 starting data transfer\n";
write(cmd_fd, start, strlen(start));
int ret = write(cmd_fd, start, strlen(start));
char* buff = (char*)malloc(5000);
int size = read(fd_map[cmd_fd], buff, 5000);
int size = recv(fd_map[cmd_fd], buff, 5000, 0);
while (size < 0) {
size = read(fd_map[cmd_fd], buff, 5000);
size = recv(fd_map[cmd_fd], buff, 5000, 0);
}
char* end = "226 Operation successfull";
char* end = "226 Operation successfull\n";
write(cmd_fd, end, strlen(end));
fwrite(buff, 1, strlen(buff), file);
@ -196,15 +207,16 @@ char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
free(dir);
}
else if(strcmp(cmd,"QUIT")==0){
sprintf(respond, "221 connection close");
sprintf(respond, "221 connection close\n");
*ret = 221;
}
else if (strcmp(cmd, "TYPE") == 0) {
sprintf(respond, "200 Type set to I");
sprintf(respond, "200 Type set to I\n");
}
else {
respond = "500 syntax error\n";
}
pthread_mutex_unlock(&mutex);
return respond;
}
@ -232,6 +244,7 @@ void *RecvSend(void *arg)
}
void StartNewConnection(int cmd_fd, struct sockaddr_in client_addr)
{
pthread_mutex_lock(&mutex);
char client_ip[INET_ADDRSTRLEN];
int client_port;
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, sizeof(client_ip));
@ -248,30 +261,30 @@ void StartNewConnection(int cmd_fd, struct sockaddr_in client_addr)
}
if (it == -1) {
for(int i=0;i<MAX_CONNECTION;i++){
if(login_list[i].login_status==0){
if(login_list[i].login_status==UNLOGED_IN && strlen(login_list[i].addr)==0){
it = i;
strcpy(login_list[i].addr, client_id);
break;
}
}
if(it==-1){
const char limit_exceeded[] = "530 connection limit exceeded.";
const char limit_exceeded[] = "530 connection limit exceeded.\n";
write(cmd_fd, limit_exceeded, strlen(limit_exceeded));
pthread_mutex_unlock(&mutex);
return;
}
}
if(login_list[it].login_status == UNLOGED_IN){
const char welcome[] = "220 welcome.";
if (login_list[it].login_status == UNLOGED_IN) {
const char welcome[] = "220 welcome.\n.";
write(cmd_fd, welcome, strlen(welcome));
}
pthread_t thread;
int arg[2];
int *arg = malloc(2);
arg[0] = cmd_fd;
arg[1] = it;
pthread_create(&thread, NULL, RecvSend, arg);
pthread_mutex_unlock(&mutex);
}
int Init() {
@ -279,6 +292,7 @@ int Init() {
for (int i = 0;i < MAX_CONNECTION;i++) {
login_list[i].addr = (char*)malloc(50);
login_list[i].login_status = UNLOGED_IN;
strcpy(login_list[i].addr, "");
}
int fd = socket(AF_INET, SOCK_STREAM, 0);
@ -293,7 +307,6 @@ int Init() {
server_addr.sin_addr.s_addr = INADDR_ANY;
int ret = bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (ret < 0) {
printf("%d\n", ret);
printf("Failed to bind socket\n");
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB