客户端代码
须要cJSON.c文件和cJSON.h文件
- 在这里插入代码片
- #include "myheadth.h"
- #include "myfun.h"
- #define TIME 10
- int sockfd;
- void heartbeat(int signum)
- {
- cJSON* root = cJSON_CreateObject();
- cJSON_AddStringToObject(root,"request","heartbeat");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- alarm(TIME);
- }
- int main(int argc,char **argv)
- {
- if(argc < 3)
- {
- fprintf(stderr,"Usage <%s SERIP SERPOST>\n",argv[0]);
- return -1;
- }
- /* 1. 创建套接字*/
- sockfd = socket(AF_INET,SOCK_STREAM,0);
- if(sockfd == -1)
- {
- perror("socket");
- return -1;
- }
- /* 2.连接服务器*/
- sin_t server = {AF_INET};
- server.sin_port = htons(atoi(argv[2]));
- server.sin_addr.s_addr = inet_addr(argv[1]);
- int len = sizeof(sin_t);
- connect(sockfd,(sad_t*)&server,len);
- //设置心跳定时器
- signal(SIGALRM,heartbeat);
- alarm(TIME);
- //函数声明
- int findall_directory(int sockfd);
- int upload_directory(int sockfd);
- int download_directory(int sockfd);
- void menu_2();
-
- while(1)
- {
- menu();
- printf("请输入你的选择:");
- int choice;
- scanf("%d",&choice);
- getchar();
- if(choice == 0)
- {
- quit(sockfd);
- alarm(TIME);
- break;
- }
- int flag = 0;
- switch(choice)
- {
- case 1:
- //用户登录
- user_login(sockfd);
- break;
- case 2:
- //用户注册
- user_register(sockfd);
- break;
- case 3:
- //用户注销
- user_logout(sockfd);
- break;
- case 4:
- // 进入二级菜单
- menu_2();
- default:
- puts("输入有误请重新输入");
- flag = 1;
- break;
- }
- if(flag)
- continue;
- /* 4. 接收服务端消息*/
- char bufs[512] = {0};
- recv(sockfd,bufs,sizeof(bufs)-1,0);
- cJSON* servers = cJSON_Parse(bufs);
- if(servers == NULL)
- {
- puts("malloc node for parse failed");
- return -1;
- }
- alarm(TIME);
-
- cJSON* itemRever = cJSON_GetObjectItem(servers,"rever");
- printf("%s\n",itemRever -> valuestring);
-
- if(strcmp(itemRever -> valuestring,"登录成功!") == 0)
- {
- while(1)
- {
- menu_2();
- printf("请输入你的选择:");
- int choice2;
- scanf("%d",&choice2);
- getchar();
- if(choice2 == 0)
- {
- alarm(TIME);
- break;
- }
- int flag2 = 0;
- switch(choice2)
- {
- case 1:
- //浏览所有目录信息
- findall_directory(sockfd);//需要修改
- break;
- case 2:
- //上传所有信息
- upload_directory(sockfd);
- break;
- case 3:
- //下载所有信息
- download_directory(sockfd);
- break;
- case 4:
- //返回上一级
- return 0;
- break;
- default:
- puts("输入有误请重新输入");
- flag = 1;
- break;
- }
- alarm(TIME);
- if(flag2)
- continue;
- }
- }
- cJSON_Delete(servers);
- servers = NULL;
- }
- /* 5. 关闭套接字*/
- close(sockfd);
- return 0;
- }
复制代码 登录界面以及功能实现
- 在这里插入代码片
- #include "myfun.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include "cJSON.h"
- void menu()
- {
- printf("\n");
- printf("\033[1;36m");
- printf("================消息系统============\n");
- printf("1. 用户登录\n");
- printf("2. 用户注册\n");
- printf("3. 用户注销\n");
- printf("4. 进入功能\n");
- printf("0. 退出\n");
- printf("===================================\n");
- printf("\033[0m");
- printf("\n");
- }
- void menu_2()
- {
- printf("\n");
- printf("\033[1;36m");
- printf("================消息系统============\n");
- printf("1. 浏览所有目录信息\n");
- printf("2. 上传所有目录信息\n");
- printf("3. 下载所有目录信息\n");
- printf("0. 返回上一级\n");
- printf("===================================\n");
- printf("\033[0m");
- printf("\n");
- }
- //用户登陆
- int user_login(int sockfd)
- {
- char user[20] = {0},passwd[8] = {0};
- printf("请输入用户名:");
- fgets(user,20,stdin);
- user[strlen(user)-1] = 0;
- printf("请输入密码:");
- fgets(passwd,8,stdin);
- passwd[strlen(passwd)-1] = 0;
- cJSON* root = cJSON_CreateObject();
- if(root == NULL)
- {
- puts("malloc root node failed");
- return -1;
- }
-
- cJSON_AddStringToObject(root,"request","login");
- cJSON_AddStringToObject(root,"user",user);
- cJSON_AddStringToObject(root,"passwd",passwd);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- return 0;
- }
- //用户注册
- int user_register(int sockfd)
- {
- char user[20] = {0},passwd[8] = {0};
- printf("请输入用户名:");
- fgets(user,20,stdin);
- user[strlen(user)-1] = 0;
- // getchar();
-
- printf("请输入密码:");
- fgets(passwd,8,stdin);
- passwd[strlen(passwd)-1] = 0;
- sleep(3);
- cJSON* root = cJSON_CreateObject();
- if(root == NULL)
- {
- puts("malloc root node failed");
- return -1;
- }
-
- cJSON_AddStringToObject(root,"request","register");
- cJSON_AddStringToObject(root,"user",user);
- cJSON_AddStringToObject(root,"passwd",passwd);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- return 0;
- }
- //用户注销
- int user_logout(int sockfd)
- {
- char user[20] = {0},passwd[8] = {0};
- printf("请输入用户名:");
- fgets(user,20,stdin);
- user[strlen(user)-1] = 0;
- printf("请输入密码:");
- fgets(passwd,8,stdin);
- passwd[strlen(passwd)-1] = 0;
- cJSON* root = cJSON_CreateObject();
- if(root == NULL)
- {
- puts("malloc root node failed");
- return -1;
- }
-
- cJSON_AddStringToObject(root,"request","logout");
- cJSON_AddStringToObject(root,"user",user);
- cJSON_AddStringToObject(root,"passwd",passwd);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- return 0;
- }
- // 浏览所有目录以及文件信息
- int findall_directory(int sockfd) {
- cJSON* root = cJSON_CreateObject();
- if (root == NULL) {
- puts("malloc root node failed");
- return -1;
- }
- // 修改请求类型为 findall_directory
- cJSON_AddStringToObject(root, "request", "findall_directory");
-
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- char bufs[1024 * 1024] = {0};
- recv(sockfd, bufs, sizeof(bufs) - 1, 0);
- cJSON* directories = cJSON_Parse(bufs);
- if (directories == NULL) {
- puts("malloc node for parse failed");
- return -1;
- }
- cJSON* itemReverse = cJSON_GetObjectItem(directories, "reverse");
- if (strcmp(itemReverse->valuestring, "null") == 0) {
- cJSON_Delete(directories);
- directories = NULL;
- printf("未有目录信息\n");
- return 0;
- }
- // 解析目录信息
- cJSON* itemType = cJSON_GetObjectItem(directories, "type");
- cJSON* itemTitle = cJSON_GetObjectItem(directories, "title");
- cJSON* itemContent = cJSON_GetObjectItem(directories, "content");
- cJSON* itemData = cJSON_GetObjectItem(directories, "directory");
- // 打印目录信息
- printf("%-18s\t%-70s\t%s\n", itemType->valuestring, itemTitle->valuestring, itemContent->valuestring);
- if (cJSON_IsArray(itemData)) {
- int n = cJSON_GetArraySize(itemData);
- for (int i = 0; i < n; i++) {
- cJSON* subItem = cJSON_GetArrayItem(itemData, i);
- cJSON* itemData_name = cJSON_GetObjectItem(subItem, "name");
- cJSON* itemData_size = cJSON_GetObjectItem(subItem, "size");
- cJSON* itemData_created_date = cJSON_GetObjectItem(subItem, "created_date");
- // 打印目录的详细信息
- printf("%-30s\t%-10d\t%s\n", itemData_name->valuestring, itemData_size->valueint, itemData_created_date->valuestring);
- }
- }
- cJSON_Delete(directories);
- directories = NULL;
- return 0;
- }
- // 假设的函数,用于收集目录和文件信息到 cJSON 对象
- cJSON* collect_directory_and_file_info() {
- cJSON* root = cJSON_CreateObject();
- // 示例:添加一些目录和文件信息
- cJSON* directories = cJSON_AddArrayToObject(root, "directories");
- cJSON* files = cJSON_AddArrayToObject(root, "files");
- // 假设添加一个目录信息
- cJSON* dir1 = cJSON_CreateObject();
- cJSON_AddStringToObject(dir1, "name", "/path/to/directory");
- cJSON_AddNumberToObject(dir1, "size", 1024);
- cJSON_AddStringToObject(dir1, "created_date", "2025-01-12");
- cJSON_AddItemToArray(directories, dir1);
- // 假设添加一个文件信息
- cJSON* file1 = cJSON_CreateObject();
- cJSON_AddStringToObject(file1, "name", "/path/to/file.txt");
- cJSON_AddNumberToObject(file1, "size", 512);
- cJSON_AddStringToObject(file1, "created_date", "2025-01-11");
- cJSON_AddItemToArray(files, file1);
- return root;
- }
- // 上传所有目录以及文件信息
- int upload_directory(int sockfd) {
- cJSON* root = cJSON_CreateObject();
- if (root == NULL) {
- puts("malloc root node failed");
- return -1;
- }
- // 修改请求类型为 upload_directory
- cJSON_AddStringToObject(root, "request", "upload_directory");
- // 收集目录和文件信息
- cJSON* directory_and_file_info = collect_directory_and_file_info();
- cJSON_AddItemToObject(root, "data", directory_and_file_info);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- // 接收服务器的响应(可选)
- char bufs[1024 * 1024] = {0};
- recv(sockfd, bufs, sizeof(bufs) - 1, 0);
- cJSON* response = cJSON_Parse(bufs);
- if (response == NULL) {
- puts("malloc node for parse failed");
- return -1;
- }
- cJSON* itemReverse = cJSON_GetObjectItem(response, "reverse");
- if (strcmp(itemReverse->valuestring, "null") == 0) {
- cJSON_Delete(response);
- response = NULL;
- printf("上传失败\n");
- return -1;
- } else {
- printf("上传成功\n");
- }
- cJSON_Delete(response);
- response = NULL;
- return 0;
- }
- // 下载所有目录及文件信息
- int download_directory(int sockfd) {
- cJSON* root = cJSON_CreateObject();
- if (root == NULL) {
- puts("malloc root node failed");
- return -1;
- }
- // 修改请求类型为 download_directory
- cJSON_AddStringToObject(root, "request", "download_directory");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- // 接收服务器的响应
- char bufs[1024 * 1024] = {0};
- recv(sockfd, bufs, sizeof(bufs) - 1, 0);
- cJSON* response = cJSON_Parse(bufs);
- if (response == NULL) {
- puts("malloc node for parse failed");
- return -1;
- }
- cJSON* itemReverse = cJSON_GetObjectItem(response, "reverse");
- if (strcmp(itemReverse->valuestring, "null") == 0) {
- cJSON_Delete(response);
- response = NULL;
- printf("没有可下载的目录或文件信息\n");
- return 0;
- } else {
- printf("开始下载目录和文件信息\n");
- }
- // 解析并处理下载的目录和文件信息
- cJSON* directories = cJSON_GetObjectItem(response, "directories");
- cJSON* files = cJSON_GetObjectItem(response, "files");
- if (cJSON_IsArray(directories)) {
- int n = cJSON_GetArraySize(directories);
- for (int i = 0; i < n; i++) {
- cJSON* subItem = cJSON_GetArrayItem(directories, i);
- cJSON* dir_name = cJSON_GetObjectItem(subItem, "name");
- cJSON* dir_size = cJSON_GetObjectItem(subItem, "size");
- cJSON* dir_created_date = cJSON_GetObjectItem(subItem, "created_date");
- // 打印目录信息,可添加下载逻辑
- printf("Directory: %s, Size: %d, Created Date: %s\n", dir_name->valuestring, dir_size->valueint, dir_created_date->valuestring);
- }
- }
- if (cJSON_IsArray(files)) {
- int m = cJSON_GetArraySize(files);
- for (int i = 0; i < m; i++) {
- cJSON* subItem = cJSON_GetArrayItem(files, i);
- cJSON* file_name = cJSON_GetObjectItem(subItem, "name");
- cJSON* file_size = cJSON_GetObjectItem(subItem, "size");
- cJSON* file_created_date = cJSON_GetObjectItem(subItem, "created_date");
- // 打印文件信息,可添加下载逻辑
- printf("File: %s, Size: %d, Created Date: %s\n", file_name->valuestring, file_size->valueint, file_created_date->valuestring);
- }
- }
- cJSON_Delete(response);
- response = NULL;
- return 0;
- }
- int quit(int sockfd)
- {
- cJSON* root = cJSON_CreateObject();
- if(root == NULL)
- {
- puts("malloc root node failed");
- return -1;
- }
-
- cJSON_AddStringToObject(root,"request","quit");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- cJSON_Delete(root);
- free(JSstr1);
- root = NULL;
- return 0;
- }
复制代码 须要引用cJSON文件 json文件:
服务器端本身构建函数mufun.c
- #include "myfun.h"
- #include<dirent.h>
- #include<sys/stat.h>
- typedef unsigned long long ull;
- //数据库连接
- static MYSQL* mysql_connect()
- {
- //数据库初始化
- MYSQL* mysql = mysql_init(NULL);
- if(mysql == NULL)
- {
- fprintf(stderr,"mysql_init初始化失败\n");
- return NULL;
- }
- mysql_set_character_set(mysql,"utf8");
- //数据库连接
- if(NULL == mysql_real_connect(mysql,"localhost","root","123456","xiaohua",0,NULL,0))
- {
- fprintf(stderr,"conn:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return NULL;
- }
- return mysql;
- }
- //登录
- int login(const char* user,const char* passwd)
- {
- MYSQL* mysql = mysql_connect();
- char sql[128] = {0};
- sprintf(sql,"select * from users");
- if(mysql_real_query(mysql,sql,strlen(sql)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- //获得字符集
- MYSQL_RES *result = mysql_store_result(mysql);
- if(result == NULL)
- {
- fprintf(stderr,"store res:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- ull rnum = mysql_num_rows(result);//记录数量
- for(int i = 0; i < rnum; i++)
- {
- MYSQL_ROW row = mysql_fetch_row(result);
- if(strcmp(row[0],user) == 0 && strcmp(row[1],passwd) == 0)
- {
- mysql_free_result(result);
- char sql2[128] = {0};
- sprintf(sql2,"update users set state = 1 where username = '%s'",user);
- mysql_real_query(mysql,sql2,strlen(sql2));
- mysql_close(mysql);
- return 1;
- }
- }
- mysql_free_result(result);
- mysql_close(mysql);
- return 0;
- }
- //注册
- int regist(const char* user,const char* passwd)
- {
-
- MYSQL* mysql = mysql_connect();
- char sql1[128] = {0};
- sprintf(sql1,"create table if not exists users(username varchar(20) primary key,passwd varchar(8) not null,state int default 0)default charset=utf8");
- if(mysql_real_query(mysql,sql1,strlen(sql1)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- char sql2[128] = {0};
- sprintf(sql2,"insert into users(username,passwd) values('%s','%s')",user,passwd);
- if(mysql_real_query(mysql,sql2,strlen(sql2)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- mysql_close(mysql);
- return 1;
- }
- //注销
- int logout(const char* user,const char* passwd)
- {
- MYSQL* mysql = mysql_connect();
- char sql[128] = {0};
- sprintf(sql,"select * from users");
- if(mysql_real_query(mysql,sql,strlen(sql)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- //获得字符集
- MYSQL_RES *result = mysql_store_result(mysql);
- if(result == NULL)
- {
- mysql_close(mysql);
- return 0;
- }
- ull rnum = mysql_num_rows(result);//记录数量
- for(int i = 0; i < rnum; i++)
- {
- MYSQL_ROW row = mysql_fetch_row(result);
- if(strcmp(row[0],user) == 0 && strcmp(row[1],passwd) == 0)
- {
- char sql2[128] = {0};
- sprintf(sql2,"delete from users where username = '%s'",user);
- if(mysql_real_query(mysql,sql2,strlen(sql2)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return 0;
- }
- mysql_free_result(result);
- mysql_close(mysql);
- return 1;
- }
- }
- mysql_free_result(result);
- mysql_close(mysql);
- return 0;
- }
- // 浏览所有目录文件信息
- int findall_directory(int sockfd) {
- MYSQL* mysql = mysql_connect();
- if (mysql == NULL) {
- fprintf(stderr, "Failed to connect to MySQL database.\n");
- return -1;
- }
- char sql1[128] = {0};
- cJSON* root = cJSON_CreateObject();
- // 假设表名为 directories_files,包含目录和文件信息
- sprintf(sql1, "select * from xiaohua");
- if (mysql_real_query(mysql, sql1, strlen(sql1))) {
- fprintf(stderr, "Failed to execute SQL query: %s\n", mysql_error(mysql));
- mysql_close(mysql);
- cJSON_AddStringToObject(root, "reverse", "null");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- return 0;
- }
- MYSQL_RES *result = mysql_store_result(mysql);
- if (result == NULL) {
- fprintf(stderr, "Failed to store query result: %s\n", mysql_error(mysql));
- mysql_close(mysql);
- cJSON_AddStringToObject(root, "reverse", "null");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- return -1;
- }
- uint32_t fnum = mysql_num_fields(result);
- my_ulonglong rnum = mysql_num_rows(result);
- // 获得列名
- MYSQL_FIELD *fields = mysql_fetch_fields(result);
- cJSON_AddStringToObject(root, "reverse", "not null");
- // 假设表的列名为 dir_name, file_name, size, created_date
- cJSON_AddStringToObject(root, "dir_name", fields[0].name);
- cJSON_AddStringToObject(root, "file_name", fields[1].name);
- cJSON_AddStringToObject(root, "size", fields[2].name);
- cJSON_AddStringToObject(root, "created_date", fields[3].name);
- cJSON* array = cJSON_CreateArray();
- for (int i = 0; i < rnum; i++) {
- cJSON* obj = cJSON_CreateObject();
- MYSQL_ROW row = mysql_fetch_row(result);
- for (int j = 0; j < fnum; j++) {
- cJSON_AddStringToObject(obj, fields[j].name, row[j]);
- }
- cJSON_AddItemToArray(array, obj);
- }
- cJSON_AddItemToObject(root, "data", array);
- mysql_free_result(result);
- mysql_close(mysql);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- return 0;
- }
- // 上传所有目录文件
- int upload_directory(int sockfd) {
- cJSON* root = cJSON_CreateObject();
- cJSON* array = cJSON_CreateArray();
- // 打开当前目录
- DIR* dir = opendir(".");
- if (dir == NULL) {
- perror("opendir");
- cJSON_AddStringToObject(root, "reverse", "null");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- return -1;
- }
- struct dirent* entry;
- while ((entry = readdir(dir))!= NULL) {
- if (entry->d_name[0] == '.') continue; // 跳过隐藏文件和目录
- struct stat st;
- if (stat(entry->d_name, &st) == -1) {
- perror("stat");
- continue;
- }
- cJSON* obj = cJSON_CreateObject();
- cJSON_AddStringToObject(obj, "name", entry->d_name);
- cJSON_AddNumberToObject(obj, "size", (int)st.st_size);
- cJSON_AddStringToObject(obj, "type", S_ISDIR(st.st_mode)? "directory" : "file");
- // 获取文件的创建时间
- char time_str[20];
- strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&st.st_ctime));
- cJSON_AddStringToObject(obj, "created_date", time_str);
- cJSON_AddItemToArray(array, obj);
- }
- closedir(dir);
- cJSON_AddItemToObject(root, "data", array);
- cJSON_AddStringToObject(root, "request", "upload_directory");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- free(JSstr1);
- return 0;
- }
- // 下载所有目录文件信息
- int download_directory(int sockfd) {
- cJSON* root = cJSON_CreateObject();
- cJSON_AddStringToObject(root, "request", "download_directory");
- // 将请求信息发送到服务器
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(root);
- free(JSstr1);
- // 接收服务器的响应
- char buffer[4096];
- int bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
- if (bytes_received <= 0) {
- perror("recv");
- return -1;
- }
- buffer[bytes_received] = '\0';
- // 解析服务器的响应
- cJSON* response = cJSON_Parse(buffer);
- if (response == NULL) {
- fprintf(stderr, "Failed to parse JSON response\n");
- return -1;
- }
- // 检查服务器是否返回错误信息
- cJSON* reverse = cJSON_GetObjectItem(response, "reverse");
- if (reverse!= NULL && strcmp(reverse->valuestring, "null") == 0) {
- fprintf(stderr, "Server returned an error\n");
- cJSON_Delete(response);
- return -1;
- }
- // 假设服务器返回的数据在 "data" 键下
- cJSON* data = cJSON_GetObjectItem(response, "data");
- if (data == NULL ||!cJSON_IsArray(data)) {
- fprintf(stderr, "Invalid data format from server\n");
- cJSON_Delete(response);
- return -1;
- }
- // 遍历服务器返回的目录文件信息
- int array_size = cJSON_GetArraySize(data);
- for (int i = 0; i < array_size; i++) {
- cJSON* item = cJSON_GetArrayItem(data, i);
- if (item == NULL) continue;
- cJSON* name = cJSON_GetObjectItem(item, "name");
- cJSON* size = cJSON_GetObjectItem(item, "size");
- cJSON* type = cJSON_GetObjectItem(item, "type");
- cJSON* created_date = cJSON_GetObjectItem(item, "created_date");
- if (name == NULL || size == NULL || type == NULL || created_date == NULL) {
- fprintf(stderr, "Invalid item format from server\n");
- continue;
- }
- // 这里可以添加逻辑将文件或目录信息保存到本地
- // 例如,打印文件或目录信息
- printf("Name: %s, Size: %d, Type: %s, Created Date: %s\n", name->valuestring, size->valueint, type->valuestring, created_date->valuestring);
- }
- cJSON_Delete(response);
- return 0;
- }
- int check(int sockfd,const char* user)
- {
- MYSQL* mysql = mysql_connect();
- char sql1[128] = {0};
- cJSON* root = cJSON_CreateObject();
- sprintf(sql1,"select * from unread where username = '%s'",user);
- if(mysql_real_query(mysql,sql1,strlen(sql1)))
- {
- mysql_close(mysql);
- cJSON_AddStringToObject(root,"reverse","null");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- return 0;
- }
- MYSQL_RES *result = mysql_store_result(mysql);
- if(result == NULL)
- {
- mysql_close(mysql);
- cJSON_AddStringToObject(root,"reverse","null");
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
- return -1;
- }
- uint32_t fnum = mysql_num_fields(result);
- my_ulonglong rnum = mysql_num_rows(result);
- //获得列名
- MYSQL_FIELD *fields = mysql_fetch_fields(result);
- cJSON_AddStringToObject(root,"reverse","not null");
- cJSON_AddStringToObject(root,"type",fields[1].name);
- cJSON_AddStringToObject(root,"title",fields[2].name);
- cJSON_AddStringToObject(root,"content",fields[3].name);
- cJSON* array = cJSON_CreateArray();
- for(int i = 0; i < rnum; i++)
- {
- MYSQL_ROW row = mysql_fetch_row(result);
- cJSON* obj = cJSON_CreateObject();
- for(int j = 1; j < fnum; j++)
- {
- cJSON_AddStringToObject(obj,fields[j].name,row[j]);
- }
-
- cJSON_AddItemToArray(array,obj);
- }
- cJSON_AddItemToObject(root,"data",array);
- mysql_free_result(result);
- char sql2[128] = {0};
- sprintf(sql2,"delete from unread where username = '%s'",user);
- mysql_real_query(mysql,sql2,strlen(sql2));
- mysql_close(mysql);
- char* JSstr1 = cJSON_PrintUnformatted(root);
- send(sockfd,JSstr1,strlen(JSstr1),0);
-
- return 0;
- }
- //退出
- int quit(const char* user)
- {
- MYSQL* mysql = mysql_connect();
- char sql[128] = {0};
- sprintf(sql,"update users set state = 0 where username = '%s'",user);
- if(mysql_real_query(mysql,sql,strlen(sql)))
- {
- fprintf(stderr,"exec:%s\n",mysql_error(mysql));
- mysql_close(mysql);
- return -1;
- }
- mysql_close(mysql);
- return 0;
- }
复制代码 服务器端fock.c
- 在这里插入代码片
- #include "mysock.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include "cJSON.h"
- #include <dirent.h>
- #include <sys/stat.h>
- #include <arpa/inet.h>
- // 假设以下函数在其他地方实现,在此声明它们
- int findall_directory(int sockc);
- int download_directory(int sockc);
- int upload_directory(int sokc);
- int login(const char *user, const char *passwd);
- int regist(const char *user, const char *passwd);
- int logout(const char *user, const char *passwd);
- int quit(const char *user);
- /*监听函数,返回监听套接字*/
- int mysock_init(const char *Ip, const char *Port)
- {
- /* 1. 创建套接字*/
- int sockl = socket(AF_INET, SOCK_STREAM, 0);
- if (sockl == -1)
- return -1;
- /* 2. 绑定自己地址信息*/
- struct sockaddr_in server = {0};
- server.sin_family = AF_INET;
- server.sin_port = htons(atoi(Port));
- inet_pton(AF_INET, Ip, &server.sin_addr); //将字符串变成网络字节序
- socklen_t len = sizeof(server);
- if (-1 == bind(sockl, (struct sockaddr *)&server, len))
- {
- close(sockl);
- return -1;
- }
- /* 3. 监听客户端连接*/
- if (-1 == listen(sockl, 5))
- {
- close(sockl);
- return -1;
- }
- //返回监听套接字
- return sockl;
- }
- char user_name[20] = {0};
- /*连接函数,接收客户端连接*/
- int mysock_accept(int sockl)
- {
- struct sockaddr_in peer = {0}; //对方
- socklen_t len = sizeof(peer);
- int sockc = accept(sockl, (struct sockaddr *)&peer, &len);
- if (sockc == -1)
- return -1;
- char IP[INET_ADDRSTRLEN + 1];
- inet_ntop(AF_INET, &peer.sin_addr, IP, INET_ADDRSTRLEN);
- printf("[%s:%d]已连接\n", IP, ntohs(peer.sin_port));
- //生成连接套接字
- return sockc;
- }
- /* 接收客户端信息的函数*/
- void *from_client(void *argp)
- {
- int sockc = *(int *)argp;
- struct sockaddr_in peer = {0};
- socklen_t len = sizeof(peer);
- getpeername(sockc, (struct sockaddr *)&peer, &len);
- // 获取客户端地址信息
- while (1)
- {
- char str[512] = {0};
- int n = recv(sockc, str, sizeof(str), 0);
- if (n == 0)
- {
- printf("客户端[%s:%d]已断开连接\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
- quit(user_name);
- break;
- }
- /* 处理客户端请求*/
- to_client(str, sockc);
- }
- return NULL;
- }
- void to_client(const char *jsStr, int sockc)
- {
- /* 给客户端发消息*/
- cJSON *root = cJSON_Parse(jsStr);
- if (root == NULL)
- return;
- cJSON *itemRequest = cJSON_GetObjectItem(root, "request");
- cJSON *itemUser = cJSON_GetObjectItem(root, "user");
- cJSON *itemPasswd = cJSON_GetObjectItem(root, "passwd");
-
- //登录
- if (strcmp(itemRequest->valuestring, "login") == 0)
- {
- puts("用户登录");
- char *res[] = {"登录失败!", "登录成功!"};
- int i = login(itemUser->valuestring, itemPasswd->valuestring);
- cJSON *rever = cJSON_CreateObject();
- if (rever == NULL)
- return;
- if (i == 1)
- {
- memset(user_name, 0, 20);
- strcpy(user_name, itemUser->valuestring);
- }
- cJSON_AddStringToObject(rever, "rever", res[i]);
- char *JSstr1 = cJSON_PrintUnformatted(rever);
- send(sockc, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(rever);
- }
- //注册
- else if (strcmp(itemRequest->valuestring, "register") == 0)
- {
- puts("用户注册");
- char *res[] = {"注册失败!", "注册成功,请登录..."};
- int i = regist(itemUser->valuestring, itemPasswd->valuestring);
- cJSON *rever = cJSON_CreateObject();
- if (rever == NULL)
- return;
- cJSON_AddStringToObject(rever, "rever", res[i]);
- char *JSstr1 = cJSON_PrintUnformatted(rever);
- send(sockc, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(rever);
- }
- //注销
- else if (strcmp(itemRequest->valuestring, "logout") == 0)
- {
- puts("用户注销");
- char *res[] = {"注销失败!", "注销成功!"};
- int i = logout(itemUser->valuestring, itemPasswd->valuestring);
- cJSON *rever = cJSON_CreateObject();
- if (rever == NULL)
- return;
- cJSON_AddStringToObject(rever, "rever", res[i]);
- char *JSstr1 = cJSON_PrintUnformatted(rever);
- send(sockc, JSstr1, strlen(JSstr1), 0);
- cJSON_Delete(rever);
- }
- // 浏览所有目录文件信息
- else if (strcmp(itemRequest->valuestring, "findall_directory") == 0)
- {
- puts("浏览所有目录文件信息");
- findall_directory(sockc);
- }
- // 上传目录文件信息
- else if (strcmp(itemRequest->valuestring, "upload_directory") == 0)
- {
- puts("上传目录文件信息");
- int upload_directory(int sockc) {
- cJSON *root = cJSON_CreateObject();
- cJSON *array = cJSON_CreateArray();
- DIR *dir = opendir(".");
- if (dir == NULL) {
- perror("opendir");
- cJSON_AddStringToObject(root, "reverse", "null");
- char *JSstr = cJSON_PrintUnformatted(root);
- send(sockc, JSstr, strlen(JSstr), 0);
- cJSON_Delete(root);
- free(JSstr);
- return -1;
- }
- struct dirent *entry;
- while ((entry = readdir(dir))!= NULL) {
- if (entry->d_name[0] == '.') continue;
- struct stat st;
- if (stat(entry->d_name, &st) == -1) {
- perror("stat");
- continue;
- }
- cJSON *obj = cJSON_CreateObject();
- cJSON_AddStringToObject(obj, "name", entry->d_name);
- cJSON_AddNumberToObject(obj, "size", (int)st.st_size);
- cJSON_AddStringToObject(obj, "type", S_ISDIR(st.st_mode)? "directory" : "file");
- cJSON_AddItemToArray(array, obj);
- }
- closedir(dir);
- cJSON_AddItemToObject(root, "data", array);
- cJSON_AddStringToObject(root, "request", "upload_directory");
- char *JSstr = cJSON_PrintUnformatted(root);
- send(sockc, JSstr, strlen(JSstr), 0);
- cJSON_Delete(root);
- free(JSstr);
- return 0;
- }
- upload_directory(sockc);
- }
- // 下载所有目录信息
- else if (strcmp(itemRequest->valuestring, "download_directory") == 0)
- {
- puts("下载所有目录信息");
- // 假设 download_directory 函数的参数为 sockc
- download_directory(sockc);
- }
- //检测是否退出
- else if (strcmp(itemRequest->valuestring, "quit") == 0)
- {
- quit(user_name);
- }
- //心跳检测机制
- else if (strcmp(itemRequest->valuestring, "heartbeat") == 0)
- {
- struct sockaddr_in peer = {0}; //对方
- socklen_t len = sizeof(peer);
- getpeername(sockc, (struct sockaddr *)&peer, &len);
- char IP[INET_ADDRSTRLEN + 1];
- inet_ntop(AF_INET, &peer.sin_addr, IP, INET_ADDRSTRLEN);
- printf("[%s:%d]还在连接中\n", IP, ntohs(peer.sin_port));
- }
- cJSON_Delete(root);
- }
复制代码 服务器端 server.c
- #include "myfun.h"
- #include "mysock.h"
- #include "pthreadpool.h"
- int main(int argc,char **argv)
- {
- if(argc < 3)
- {
- fprintf(stderr,"Usage <%s SERIP SERPOST>\n",argv[0]);
- return -1;
- }
- //调用函数
- threadpool_t pool;
- threadpool_init(&pool,8,10);
- /* 1. 调用监听函数*/
- int sockl = mysock_init(argv[1],argv[2]);
- if(sockl == -1)
- {
- perror("mysock_init");
- return -1;
- }
-
- while(1)
- {
- /* 2.调用连接函数,接收客户端连接*/
- int sockc = mysock_accept(sockl);
- if(sockc == -1)
- continue;
-
- threadpool_addtask(&pool,from_client,(void*)(uint64_t)sockc);
- }
- return 0;
- }
复制代码 服务器pthreadPool.c
- #include "pthreadpool.h"
- #include <stdlib.h>
- void* thread_fun(void *argp)
- {
- threadpool_t* pool = (threadpool_t*)argp;
- task_t *p = NULL;
- while(1)
- {
- //互斥锁
- pthread_mutex_lock(&pool->mutex);
- //判断队列情况
- //任务队列为空等待
- while(pool -> queue_num == 0)
- pthread_cond_wait(&pool->queue_empty,&pool->mutex);
- //任务队列不为空,被线程池中线程竞争
- p = pool -> head;
- pool -> queue_num--;
- //表示任务队列只有一个节点
- if(pool -> queue_num == 0)
- pool -> head = pool -> tail = NULL;
- else
- pool -> head = p -> next;
- //判断任务队列是否为满通知其他线程
- if(pool->queue_num == pool -> queue_max_size -1)
- pthread_cond_signal(&pool->queue_full);
- pthread_mutex_unlock(&pool->mutex);
- //调用函数
- (*(p -> taskfun))(p -> argp);
- //调用完毕回收资源
- free(p);
- p = NULL;
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |