一.项目课题 <基于TCP的文件传输协议实现>

打印 上一主题 下一主题

主题 820|帖子 820|积分 2460


客户端代码
须要cJSON.c文件和cJSON.h文件
  1. 在这里插入代码片
  2. #include "myheadth.h"
  3. #include "myfun.h"
  4. #define TIME 10
  5. int sockfd;
  6. void heartbeat(int signum)
  7. {
  8.     cJSON* root = cJSON_CreateObject();
  9.     cJSON_AddStringToObject(root,"request","heartbeat");        
  10.     char* JSstr1 = cJSON_PrintUnformatted(root);
  11.     send(sockfd,JSstr1,strlen(JSstr1),0);
  12.     cJSON_Delete(root);
  13.     free(JSstr1);
  14.     root = NULL;
  15.     alarm(TIME);
  16. }
  17. int main(int argc,char **argv)
  18. {
  19.     if(argc < 3)
  20.     {
  21.         fprintf(stderr,"Usage <%s SERIP SERPOST>\n",argv[0]);
  22.         return -1;
  23.     }
  24.     /* 1. 创建套接字*/
  25.     sockfd = socket(AF_INET,SOCK_STREAM,0);
  26.     if(sockfd == -1)
  27.     {
  28.         perror("socket");
  29.         return -1;
  30.     }
  31.     /* 2.连接服务器*/
  32.     sin_t server = {AF_INET};
  33.     server.sin_port = htons(atoi(argv[2]));
  34.     server.sin_addr.s_addr = inet_addr(argv[1]);
  35.     int len = sizeof(sin_t);
  36.     connect(sockfd,(sad_t*)&server,len);
  37.     //设置心跳定时器
  38.     signal(SIGALRM,heartbeat);
  39.     alarm(TIME);
  40. //函数声明
  41. int findall_directory(int sockfd);
  42. int upload_directory(int sockfd);
  43. int download_directory(int sockfd);
  44. void menu_2();
  45.    
  46.     while(1)
  47.     {
  48.         menu();
  49.         printf("请输入你的选择:");
  50.         int choice;
  51.         scanf("%d",&choice);
  52.         getchar();
  53.         if(choice == 0)
  54.         {
  55.             quit(sockfd);
  56.             alarm(TIME);
  57.             break;
  58.         }
  59.         int flag = 0;
  60.         switch(choice)
  61.         {
  62.             case 1:
  63.                 //用户登录
  64.                 user_login(sockfd);
  65.                 break;
  66.             case 2:
  67.                 //用户注册
  68.                 user_register(sockfd);
  69.                 break;
  70.             case 3:
  71.                 //用户注销
  72.                 user_logout(sockfd);
  73.                 break;  
  74.             case 4:
  75.             // 进入二级菜单
  76.                menu_2();
  77.             default:
  78.                 puts("输入有误请重新输入");
  79.                 flag = 1;
  80.                 break;
  81.         }
  82.         if(flag)
  83.             continue;
  84.         /* 4. 接收服务端消息*/
  85.         char bufs[512] = {0};
  86.         recv(sockfd,bufs,sizeof(bufs)-1,0);
  87.         cJSON* servers = cJSON_Parse(bufs);
  88.         if(servers == NULL)
  89.         {
  90.             puts("malloc  node for parse failed");
  91.             return -1;
  92.         }
  93.         alarm(TIME);
  94.             
  95.         cJSON* itemRever = cJSON_GetObjectItem(servers,"rever");
  96.         printf("%s\n",itemRever -> valuestring);
  97.         
  98.         if(strcmp(itemRever -> valuestring,"登录成功!") == 0)
  99.         {
  100.             while(1)
  101.             {
  102.                 menu_2();
  103.                 printf("请输入你的选择:");
  104.                 int choice2;
  105.                 scanf("%d",&choice2);
  106.                 getchar();
  107.                 if(choice2 == 0)
  108.                 {
  109.                     alarm(TIME);
  110.                     break;
  111.                 }
  112.                 int flag2 = 0;
  113.                 switch(choice2)
  114.                 {
  115.                     case 1:
  116.                         //浏览所有目录信息
  117.                         findall_directory(sockfd);//需要修改
  118.                         break;
  119.                     case 2:
  120.                         //上传所有信息
  121.                         upload_directory(sockfd);
  122.                         break;
  123.                     case 3:
  124.                         //下载所有信息
  125.                         download_directory(sockfd);
  126.                         break;
  127.                     case 4:
  128.                         //返回上一级
  129.                         return  0;
  130.                         break;
  131.                     default:
  132.                         puts("输入有误请重新输入");
  133.                         flag = 1;
  134.                         break;
  135.                 }
  136.                 alarm(TIME);
  137.                 if(flag2)
  138.                     continue;
  139.             }
  140.         }
  141.         cJSON_Delete(servers);
  142.         servers = NULL;
  143.     }
  144.     /* 5. 关闭套接字*/
  145.     close(sockfd);
  146.     return 0;
  147. }
复制代码
登录界面以及功能实现
  1. 在这里插入代码片
  2. #include "myfun.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/socket.h>
  7. #include "cJSON.h"
  8. void menu()
  9. {
  10.     printf("\n");
  11.     printf("\033[1;36m");
  12.     printf("================消息系统============\n");
  13.     printf("1. 用户登录\n");
  14.     printf("2. 用户注册\n");
  15.     printf("3. 用户注销\n");
  16.     printf("4. 进入功能\n");
  17.     printf("0. 退出\n");
  18.     printf("===================================\n");
  19.     printf("\033[0m");
  20.     printf("\n");
  21. }
  22. void menu_2()
  23. {
  24.     printf("\n");
  25.     printf("\033[1;36m");
  26.     printf("================消息系统============\n");
  27.     printf("1. 浏览所有目录信息\n");
  28.     printf("2. 上传所有目录信息\n");
  29.     printf("3. 下载所有目录信息\n");
  30.     printf("0. 返回上一级\n");
  31.     printf("===================================\n");
  32.     printf("\033[0m");
  33.     printf("\n");
  34. }
  35. //用户登陆
  36. int user_login(int sockfd)
  37. {
  38.     char user[20] = {0},passwd[8] = {0};
  39.     printf("请输入用户名:");
  40.     fgets(user,20,stdin);
  41.     user[strlen(user)-1] = 0;
  42.     printf("请输入密码:");
  43.     fgets(passwd,8,stdin);
  44.     passwd[strlen(passwd)-1] = 0;
  45.     cJSON* root = cJSON_CreateObject();
  46.     if(root == NULL)
  47.     {
  48.         puts("malloc root node failed");
  49.         return -1;
  50.     }
  51.         
  52.     cJSON_AddStringToObject(root,"request","login");        
  53.     cJSON_AddStringToObject(root,"user",user);      
  54.     cJSON_AddStringToObject(root,"passwd",passwd);
  55.     char* JSstr1 = cJSON_PrintUnformatted(root);
  56.     send(sockfd,JSstr1,strlen(JSstr1),0);
  57.     cJSON_Delete(root);
  58.     free(JSstr1);
  59.     root = NULL;
  60.     return 0;
  61. }
  62. //用户注册
  63. int user_register(int sockfd)
  64. {
  65.     char user[20] = {0},passwd[8] = {0};
  66.     printf("请输入用户名:");
  67.     fgets(user,20,stdin);
  68.     user[strlen(user)-1] = 0;
  69.     // getchar();
  70.    
  71.     printf("请输入密码:");
  72.     fgets(passwd,8,stdin);
  73.     passwd[strlen(passwd)-1] = 0;
  74.     sleep(3);
  75.     cJSON* root = cJSON_CreateObject();
  76.     if(root == NULL)
  77.     {
  78.         puts("malloc root node failed");
  79.         return -1;
  80.     }
  81.         
  82.     cJSON_AddStringToObject(root,"request","register");        
  83.     cJSON_AddStringToObject(root,"user",user);      
  84.     cJSON_AddStringToObject(root,"passwd",passwd);
  85.     char* JSstr1 = cJSON_PrintUnformatted(root);
  86.     send(sockfd,JSstr1,strlen(JSstr1),0);
  87.     cJSON_Delete(root);
  88.     free(JSstr1);
  89.     root = NULL;
  90.     return 0;
  91. }
  92. //用户注销
  93. int user_logout(int sockfd)
  94. {
  95.     char user[20] = {0},passwd[8] = {0};
  96.     printf("请输入用户名:");
  97.     fgets(user,20,stdin);
  98.     user[strlen(user)-1] = 0;
  99.     printf("请输入密码:");
  100.     fgets(passwd,8,stdin);
  101.     passwd[strlen(passwd)-1] = 0;
  102.     cJSON* root = cJSON_CreateObject();
  103.     if(root == NULL)
  104.     {
  105.         puts("malloc root node failed");
  106.         return -1;
  107.     }
  108.         
  109.     cJSON_AddStringToObject(root,"request","logout");        
  110.     cJSON_AddStringToObject(root,"user",user);      
  111.     cJSON_AddStringToObject(root,"passwd",passwd);
  112.     char* JSstr1 = cJSON_PrintUnformatted(root);
  113.     send(sockfd,JSstr1,strlen(JSstr1),0);
  114.     cJSON_Delete(root);
  115.     free(JSstr1);
  116.     root = NULL;
  117.     return 0;
  118. }
  119. // 浏览所有目录以及文件信息
  120. int findall_directory(int sockfd) {
  121.     cJSON* root = cJSON_CreateObject();
  122.     if (root == NULL) {
  123.         puts("malloc root node failed");
  124.         return -1;
  125.     }
  126.     // 修改请求类型为 findall_directory
  127.     cJSON_AddStringToObject(root, "request", "findall_directory");
  128.    
  129.     char* JSstr1 = cJSON_PrintUnformatted(root);
  130.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  131.     cJSON_Delete(root);
  132.     free(JSstr1);
  133.     root = NULL;
  134.     char bufs[1024 * 1024] = {0};
  135.     recv(sockfd, bufs, sizeof(bufs) - 1, 0);
  136.     cJSON* directories = cJSON_Parse(bufs);
  137.     if (directories == NULL) {
  138.         puts("malloc node for parse failed");
  139.         return -1;
  140.     }
  141.     cJSON* itemReverse = cJSON_GetObjectItem(directories, "reverse");
  142.     if (strcmp(itemReverse->valuestring, "null") == 0) {
  143.         cJSON_Delete(directories);
  144.         directories = NULL;
  145.         printf("未有目录信息\n");
  146.         return 0;
  147.     }
  148.     // 解析目录信息
  149.     cJSON* itemType = cJSON_GetObjectItem(directories, "type");
  150.     cJSON* itemTitle = cJSON_GetObjectItem(directories, "title");
  151.     cJSON* itemContent = cJSON_GetObjectItem(directories, "content");
  152.     cJSON* itemData = cJSON_GetObjectItem(directories, "directory");
  153.     // 打印目录信息
  154.     printf("%-18s\t%-70s\t%s\n", itemType->valuestring, itemTitle->valuestring, itemContent->valuestring);
  155.     if (cJSON_IsArray(itemData)) {
  156.         int n = cJSON_GetArraySize(itemData);
  157.         for (int i = 0; i < n; i++) {
  158.             cJSON* subItem = cJSON_GetArrayItem(itemData, i);
  159.             cJSON* itemData_name = cJSON_GetObjectItem(subItem, "name");
  160.             cJSON* itemData_size = cJSON_GetObjectItem(subItem, "size");
  161.             cJSON* itemData_created_date = cJSON_GetObjectItem(subItem, "created_date");
  162.             // 打印目录的详细信息
  163.             printf("%-30s\t%-10d\t%s\n", itemData_name->valuestring, itemData_size->valueint, itemData_created_date->valuestring);
  164.         }
  165.     }
  166.     cJSON_Delete(directories);
  167.     directories = NULL;
  168.     return 0;
  169. }
  170. // 假设的函数,用于收集目录和文件信息到 cJSON 对象
  171. cJSON* collect_directory_and_file_info() {
  172.     cJSON* root = cJSON_CreateObject();
  173.     // 示例:添加一些目录和文件信息
  174.     cJSON* directories = cJSON_AddArrayToObject(root, "directories");
  175.     cJSON* files = cJSON_AddArrayToObject(root, "files");
  176.     // 假设添加一个目录信息
  177.     cJSON* dir1 = cJSON_CreateObject();
  178.     cJSON_AddStringToObject(dir1, "name", "/path/to/directory");
  179.     cJSON_AddNumberToObject(dir1, "size", 1024);
  180.     cJSON_AddStringToObject(dir1, "created_date", "2025-01-12");
  181.     cJSON_AddItemToArray(directories, dir1);
  182.     // 假设添加一个文件信息
  183.     cJSON* file1 = cJSON_CreateObject();
  184.     cJSON_AddStringToObject(file1, "name", "/path/to/file.txt");
  185.     cJSON_AddNumberToObject(file1, "size", 512);
  186.     cJSON_AddStringToObject(file1, "created_date", "2025-01-11");
  187.     cJSON_AddItemToArray(files, file1);
  188.     return root;
  189. }
  190. // 上传所有目录以及文件信息
  191. int upload_directory(int sockfd) {
  192.     cJSON* root = cJSON_CreateObject();
  193.     if (root == NULL) {
  194.         puts("malloc root node failed");
  195.         return -1;
  196.     }
  197.     // 修改请求类型为 upload_directory
  198.     cJSON_AddStringToObject(root, "request", "upload_directory");
  199.     // 收集目录和文件信息
  200.     cJSON* directory_and_file_info = collect_directory_and_file_info();
  201.     cJSON_AddItemToObject(root, "data", directory_and_file_info);
  202.     char* JSstr1 = cJSON_PrintUnformatted(root);
  203.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  204.     cJSON_Delete(root);
  205.     free(JSstr1);
  206.     root = NULL;
  207.     // 接收服务器的响应(可选)
  208.     char bufs[1024 * 1024] = {0};
  209.     recv(sockfd, bufs, sizeof(bufs) - 1, 0);
  210.     cJSON* response = cJSON_Parse(bufs);
  211.     if (response == NULL) {
  212.         puts("malloc node for parse failed");
  213.         return -1;
  214.     }
  215.     cJSON* itemReverse = cJSON_GetObjectItem(response, "reverse");
  216.     if (strcmp(itemReverse->valuestring, "null") == 0) {
  217.         cJSON_Delete(response);
  218.         response = NULL;
  219.         printf("上传失败\n");
  220.         return -1;
  221.     } else {
  222.         printf("上传成功\n");
  223.     }
  224.     cJSON_Delete(response);
  225.     response = NULL;
  226.     return 0;
  227. }
  228. // 下载所有目录及文件信息
  229. int download_directory(int sockfd) {
  230.     cJSON* root = cJSON_CreateObject();
  231.     if (root == NULL) {
  232.         puts("malloc root node failed");
  233.         return -1;
  234.     }
  235.     // 修改请求类型为 download_directory
  236.     cJSON_AddStringToObject(root, "request", "download_directory");
  237.     char* JSstr1 = cJSON_PrintUnformatted(root);
  238.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  239.     cJSON_Delete(root);
  240.     free(JSstr1);
  241.     root = NULL;
  242.     // 接收服务器的响应
  243.     char bufs[1024 * 1024] = {0};
  244.     recv(sockfd, bufs, sizeof(bufs) - 1, 0);
  245.     cJSON* response = cJSON_Parse(bufs);
  246.     if (response == NULL) {
  247.         puts("malloc node for parse failed");
  248.         return -1;
  249.     }
  250.     cJSON* itemReverse = cJSON_GetObjectItem(response, "reverse");
  251.     if (strcmp(itemReverse->valuestring, "null") == 0) {
  252.         cJSON_Delete(response);
  253.         response = NULL;
  254.         printf("没有可下载的目录或文件信息\n");
  255.         return 0;
  256.     } else {
  257.         printf("开始下载目录和文件信息\n");
  258.     }
  259.     // 解析并处理下载的目录和文件信息
  260.     cJSON* directories = cJSON_GetObjectItem(response, "directories");
  261.     cJSON* files = cJSON_GetObjectItem(response, "files");
  262.     if (cJSON_IsArray(directories)) {
  263.         int n = cJSON_GetArraySize(directories);
  264.         for (int i = 0; i < n; i++) {
  265.             cJSON* subItem = cJSON_GetArrayItem(directories, i);
  266.             cJSON* dir_name = cJSON_GetObjectItem(subItem, "name");
  267.             cJSON* dir_size = cJSON_GetObjectItem(subItem, "size");
  268.             cJSON* dir_created_date = cJSON_GetObjectItem(subItem, "created_date");
  269.             // 打印目录信息,可添加下载逻辑
  270.             printf("Directory: %s, Size: %d, Created Date: %s\n", dir_name->valuestring, dir_size->valueint, dir_created_date->valuestring);
  271.         }
  272.     }
  273.     if (cJSON_IsArray(files)) {
  274.         int m = cJSON_GetArraySize(files);
  275.         for (int i = 0; i < m; i++) {
  276.             cJSON* subItem = cJSON_GetArrayItem(files, i);
  277.             cJSON* file_name = cJSON_GetObjectItem(subItem, "name");
  278.             cJSON* file_size = cJSON_GetObjectItem(subItem, "size");
  279.             cJSON* file_created_date = cJSON_GetObjectItem(subItem, "created_date");
  280.             // 打印文件信息,可添加下载逻辑
  281.             printf("File: %s, Size: %d, Created Date: %s\n", file_name->valuestring, file_size->valueint, file_created_date->valuestring);
  282.         }
  283.     }
  284.     cJSON_Delete(response);
  285.     response = NULL;
  286.     return 0;
  287. }
  288. int quit(int sockfd)
  289. {
  290.     cJSON* root = cJSON_CreateObject();
  291.     if(root == NULL)
  292.     {
  293.         puts("malloc root node failed");
  294.         return -1;
  295.     }
  296.         
  297.     cJSON_AddStringToObject(root,"request","quit");        
  298.     char* JSstr1 = cJSON_PrintUnformatted(root);
  299.     send(sockfd,JSstr1,strlen(JSstr1),0);
  300.     cJSON_Delete(root);
  301.     free(JSstr1);
  302.     root = NULL;
  303.     return 0;
  304. }
复制代码
须要引用cJSON文件 json文件:
服务器端本身构建函数mufun.c
  1. #include "myfun.h"
  2. #include<dirent.h>
  3. #include<sys/stat.h>
  4. typedef unsigned long long ull;
  5. //数据库连接
  6. static MYSQL* mysql_connect()
  7. {
  8.     //数据库初始化
  9.     MYSQL* mysql = mysql_init(NULL);
  10.     if(mysql == NULL)
  11.     {
  12.         fprintf(stderr,"mysql_init初始化失败\n");
  13.         return NULL;
  14.     }
  15.     mysql_set_character_set(mysql,"utf8");
  16.     //数据库连接
  17.     if(NULL == mysql_real_connect(mysql,"localhost","root","123456","xiaohua",0,NULL,0))
  18.     {
  19.         fprintf(stderr,"conn:%s\n",mysql_error(mysql));
  20.         mysql_close(mysql);
  21.         return NULL;
  22.     }
  23.     return mysql;
  24. }
  25. //登录
  26. int login(const char* user,const char* passwd)
  27. {
  28.     MYSQL* mysql = mysql_connect();
  29.     char sql[128] = {0};
  30.     sprintf(sql,"select * from users");
  31.     if(mysql_real_query(mysql,sql,strlen(sql)))
  32.     {
  33.         fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  34.         mysql_close(mysql);
  35.         return 0;
  36.     }
  37.     //获得字符集
  38.     MYSQL_RES *result = mysql_store_result(mysql);
  39.     if(result == NULL)
  40.     {
  41.         fprintf(stderr,"store res:%s\n",mysql_error(mysql));
  42.         mysql_close(mysql);
  43.         return 0;
  44.     }
  45.     ull rnum = mysql_num_rows(result);//记录数量
  46.     for(int i = 0; i  < rnum; i++)
  47.     {
  48.         MYSQL_ROW row = mysql_fetch_row(result);
  49.         if(strcmp(row[0],user) == 0 && strcmp(row[1],passwd) == 0)
  50.         {
  51.             mysql_free_result(result);
  52.             char sql2[128] = {0};
  53.             sprintf(sql2,"update users set state = 1 where username = '%s'",user);
  54.             mysql_real_query(mysql,sql2,strlen(sql2));
  55.             mysql_close(mysql);
  56.             return 1;
  57.         }
  58.     }
  59.     mysql_free_result(result);
  60.     mysql_close(mysql);
  61.     return 0;
  62. }
  63. //注册
  64. int regist(const char* user,const char* passwd)
  65. {
  66.    
  67.     MYSQL* mysql = mysql_connect();
  68.     char sql1[128] = {0};
  69.     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");
  70.     if(mysql_real_query(mysql,sql1,strlen(sql1)))
  71.     {
  72.         fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  73.         mysql_close(mysql);
  74.         return 0;
  75.     }
  76.     char sql2[128] = {0};
  77.     sprintf(sql2,"insert into users(username,passwd) values('%s','%s')",user,passwd);
  78.     if(mysql_real_query(mysql,sql2,strlen(sql2)))
  79.     {
  80.         fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  81.         mysql_close(mysql);
  82.         return 0;
  83.     }
  84.     mysql_close(mysql);
  85.     return 1;
  86. }
  87. //注销
  88. int logout(const char* user,const char* passwd)
  89. {
  90.     MYSQL* mysql = mysql_connect();
  91.     char sql[128] = {0};
  92.     sprintf(sql,"select * from users");
  93.     if(mysql_real_query(mysql,sql,strlen(sql)))
  94.     {
  95.         fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  96.         mysql_close(mysql);
  97.         return 0;
  98.     }
  99.     //获得字符集
  100.     MYSQL_RES *result = mysql_store_result(mysql);
  101.     if(result == NULL)
  102.     {
  103.         mysql_close(mysql);
  104.         return 0;
  105.     }
  106.     ull rnum = mysql_num_rows(result);//记录数量
  107.     for(int i = 0; i  < rnum; i++)
  108.     {
  109.         MYSQL_ROW row = mysql_fetch_row(result);
  110.         if(strcmp(row[0],user) == 0 && strcmp(row[1],passwd) == 0)
  111.         {
  112.             char sql2[128] = {0};
  113.             sprintf(sql2,"delete from users where username = '%s'",user);
  114.             if(mysql_real_query(mysql,sql2,strlen(sql2)))
  115.             {
  116.                 fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  117.                 mysql_close(mysql);
  118.                 return 0;
  119.             }
  120.             mysql_free_result(result);
  121.             mysql_close(mysql);
  122.             return 1;
  123.         }
  124.     }
  125.     mysql_free_result(result);
  126.     mysql_close(mysql);
  127.     return 0;   
  128. }
  129. // 浏览所有目录文件信息
  130. int findall_directory(int sockfd) {
  131.     MYSQL* mysql = mysql_connect();
  132.     if (mysql == NULL) {
  133.         fprintf(stderr, "Failed to connect to MySQL database.\n");
  134.         return -1;
  135.     }
  136.     char sql1[128] = {0};
  137.     cJSON* root = cJSON_CreateObject();
  138.     // 假设表名为 directories_files,包含目录和文件信息
  139.     sprintf(sql1, "select * from xiaohua");
  140.     if (mysql_real_query(mysql, sql1, strlen(sql1))) {
  141.         fprintf(stderr, "Failed to execute SQL query: %s\n", mysql_error(mysql));
  142.         mysql_close(mysql);
  143.         cJSON_AddStringToObject(root, "reverse", "null");
  144.         char* JSstr1 = cJSON_PrintUnformatted(root);
  145.         send(sockfd, JSstr1, strlen(JSstr1), 0);
  146.         return 0;
  147.     }
  148.     MYSQL_RES *result = mysql_store_result(mysql);
  149.     if (result == NULL) {
  150.         fprintf(stderr, "Failed to store query result: %s\n", mysql_error(mysql));
  151.         mysql_close(mysql);
  152.         cJSON_AddStringToObject(root, "reverse", "null");
  153.         char* JSstr1 = cJSON_PrintUnformatted(root);
  154.         send(sockfd, JSstr1, strlen(JSstr1), 0);
  155.         return -1;
  156.     }
  157.     uint32_t fnum = mysql_num_fields(result);
  158.     my_ulonglong rnum = mysql_num_rows(result);
  159.     // 获得列名
  160.     MYSQL_FIELD *fields = mysql_fetch_fields(result);
  161.     cJSON_AddStringToObject(root, "reverse", "not null");
  162.     // 假设表的列名为 dir_name, file_name, size, created_date
  163.     cJSON_AddStringToObject(root, "dir_name", fields[0].name);
  164.     cJSON_AddStringToObject(root, "file_name", fields[1].name);
  165.     cJSON_AddStringToObject(root, "size", fields[2].name);
  166.     cJSON_AddStringToObject(root, "created_date", fields[3].name);
  167.     cJSON* array = cJSON_CreateArray();
  168.     for (int i = 0; i < rnum; i++) {
  169.         cJSON* obj = cJSON_CreateObject();
  170.         MYSQL_ROW row = mysql_fetch_row(result);
  171.         for (int j = 0; j < fnum; j++) {
  172.             cJSON_AddStringToObject(obj, fields[j].name, row[j]);
  173.         }
  174.         cJSON_AddItemToArray(array, obj);
  175.     }
  176.     cJSON_AddItemToObject(root, "data", array);
  177.     mysql_free_result(result);
  178.     mysql_close(mysql);
  179.     char* JSstr1 = cJSON_PrintUnformatted(root);
  180.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  181.     cJSON_Delete(root);
  182.     return 0;
  183. }
  184. // 上传所有目录文件
  185. int upload_directory(int sockfd) {
  186.     cJSON* root = cJSON_CreateObject();
  187.     cJSON* array = cJSON_CreateArray();
  188.     // 打开当前目录
  189.     DIR* dir = opendir(".");
  190.     if (dir == NULL) {
  191.         perror("opendir");
  192.         cJSON_AddStringToObject(root, "reverse", "null");
  193.         char* JSstr1 = cJSON_PrintUnformatted(root);
  194.         send(sockfd, JSstr1, strlen(JSstr1), 0);
  195.         cJSON_Delete(root);
  196.         return -1;
  197.     }
  198.     struct dirent* entry;
  199.     while ((entry = readdir(dir))!= NULL) {
  200.         if (entry->d_name[0] == '.') continue; // 跳过隐藏文件和目录
  201.         struct stat st;
  202.         if (stat(entry->d_name, &st) == -1) {
  203.             perror("stat");
  204.             continue;
  205.         }
  206.         cJSON* obj = cJSON_CreateObject();
  207.         cJSON_AddStringToObject(obj, "name", entry->d_name);
  208.         cJSON_AddNumberToObject(obj, "size", (int)st.st_size);
  209.         cJSON_AddStringToObject(obj, "type", S_ISDIR(st.st_mode)? "directory" : "file");
  210.         // 获取文件的创建时间
  211.         char time_str[20];
  212.         strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&st.st_ctime));
  213.         cJSON_AddStringToObject(obj, "created_date", time_str);
  214.         cJSON_AddItemToArray(array, obj);
  215.     }
  216.     closedir(dir);
  217.     cJSON_AddItemToObject(root, "data", array);
  218.     cJSON_AddStringToObject(root, "request", "upload_directory");
  219.     char* JSstr1 = cJSON_PrintUnformatted(root);
  220.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  221.     cJSON_Delete(root);
  222.     free(JSstr1);
  223.     return 0;
  224. }
  225. // 下载所有目录文件信息
  226. int download_directory(int sockfd) {
  227.     cJSON* root = cJSON_CreateObject();
  228.     cJSON_AddStringToObject(root, "request", "download_directory");
  229.     // 将请求信息发送到服务器
  230.     char* JSstr1 = cJSON_PrintUnformatted(root);
  231.     send(sockfd, JSstr1, strlen(JSstr1), 0);
  232.     cJSON_Delete(root);
  233.     free(JSstr1);
  234.     // 接收服务器的响应
  235.     char buffer[4096];
  236.     int bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
  237.     if (bytes_received <= 0) {
  238.         perror("recv");
  239.         return -1;
  240.     }
  241.     buffer[bytes_received] = '\0';
  242.     // 解析服务器的响应
  243.     cJSON* response = cJSON_Parse(buffer);
  244.     if (response == NULL) {
  245.         fprintf(stderr, "Failed to parse JSON response\n");
  246.         return -1;
  247.     }
  248.     // 检查服务器是否返回错误信息
  249.     cJSON* reverse = cJSON_GetObjectItem(response, "reverse");
  250.     if (reverse!= NULL && strcmp(reverse->valuestring, "null") == 0) {
  251.         fprintf(stderr, "Server returned an error\n");
  252.         cJSON_Delete(response);
  253.         return -1;
  254.     }
  255.     // 假设服务器返回的数据在 "data" 键下
  256.     cJSON* data = cJSON_GetObjectItem(response, "data");
  257.     if (data == NULL ||!cJSON_IsArray(data)) {
  258.         fprintf(stderr, "Invalid data format from server\n");
  259.         cJSON_Delete(response);
  260.         return -1;
  261.     }
  262.     // 遍历服务器返回的目录文件信息
  263.     int array_size = cJSON_GetArraySize(data);
  264.     for (int i = 0; i < array_size; i++) {
  265.         cJSON* item = cJSON_GetArrayItem(data, i);
  266.         if (item == NULL) continue;
  267.         cJSON* name = cJSON_GetObjectItem(item, "name");
  268.         cJSON* size = cJSON_GetObjectItem(item, "size");
  269.         cJSON* type = cJSON_GetObjectItem(item, "type");
  270.         cJSON* created_date = cJSON_GetObjectItem(item, "created_date");
  271.         if (name == NULL || size == NULL || type == NULL || created_date == NULL) {
  272.             fprintf(stderr, "Invalid item format from server\n");
  273.             continue;
  274.         }
  275.         // 这里可以添加逻辑将文件或目录信息保存到本地
  276.         // 例如,打印文件或目录信息
  277.         printf("Name: %s, Size: %d, Type: %s, Created Date: %s\n", name->valuestring, size->valueint, type->valuestring, created_date->valuestring);
  278.     }
  279.     cJSON_Delete(response);
  280.     return 0;
  281. }
  282. int check(int sockfd,const char* user)
  283. {
  284.     MYSQL* mysql = mysql_connect();
  285.     char sql1[128] = {0};
  286.     cJSON* root = cJSON_CreateObject();
  287.     sprintf(sql1,"select * from unread where username = '%s'",user);
  288.     if(mysql_real_query(mysql,sql1,strlen(sql1)))
  289.     {
  290.         mysql_close(mysql);
  291.         cJSON_AddStringToObject(root,"reverse","null");
  292.         char* JSstr1 = cJSON_PrintUnformatted(root);
  293.         send(sockfd,JSstr1,strlen(JSstr1),0);
  294.         return 0;
  295.     }
  296.     MYSQL_RES *result = mysql_store_result(mysql);
  297.     if(result == NULL)
  298.     {
  299.         mysql_close(mysql);
  300.         cJSON_AddStringToObject(root,"reverse","null");
  301.         char* JSstr1 = cJSON_PrintUnformatted(root);
  302.         send(sockfd,JSstr1,strlen(JSstr1),0);
  303.         return -1;
  304.     }
  305.     uint32_t      fnum = mysql_num_fields(result);
  306.     my_ulonglong  rnum = mysql_num_rows(result);
  307.     //获得列名
  308.     MYSQL_FIELD *fields = mysql_fetch_fields(result);
  309.     cJSON_AddStringToObject(root,"reverse","not null");
  310.     cJSON_AddStringToObject(root,"type",fields[1].name);
  311.     cJSON_AddStringToObject(root,"title",fields[2].name);
  312.     cJSON_AddStringToObject(root,"content",fields[3].name);
  313.     cJSON* array = cJSON_CreateArray();
  314.     for(int i = 0; i  < rnum; i++)
  315.     {
  316.         MYSQL_ROW  row = mysql_fetch_row(result);
  317.         cJSON* obj = cJSON_CreateObject();
  318.         for(int j = 1; j < fnum; j++)
  319.         {
  320.             cJSON_AddStringToObject(obj,fields[j].name,row[j]);
  321.         }
  322.             
  323.         cJSON_AddItemToArray(array,obj);
  324.     }
  325.     cJSON_AddItemToObject(root,"data",array);
  326.     mysql_free_result(result);
  327.     char sql2[128] = {0};
  328.     sprintf(sql2,"delete from unread where username = '%s'",user);
  329.     mysql_real_query(mysql,sql2,strlen(sql2));
  330.     mysql_close(mysql);
  331.     char* JSstr1 = cJSON_PrintUnformatted(root);
  332.     send(sockfd,JSstr1,strlen(JSstr1),0);
  333.    
  334.     return 0;
  335. }
  336. //退出
  337. int quit(const char* user)
  338. {
  339.     MYSQL* mysql = mysql_connect();
  340.     char sql[128] = {0};
  341.     sprintf(sql,"update users set state = 0 where username = '%s'",user);
  342.     if(mysql_real_query(mysql,sql,strlen(sql)))
  343.     {
  344.         fprintf(stderr,"exec:%s\n",mysql_error(mysql));
  345.         mysql_close(mysql);
  346.         return -1;
  347.     }
  348.     mysql_close(mysql);
  349.     return 0;
  350. }
复制代码
服务器端fock.c
  1. 在这里插入代码片
  2. #include "mysock.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/socket.h>
  7. #include "cJSON.h"
  8. #include <dirent.h>
  9. #include <sys/stat.h>
  10. #include <arpa/inet.h>
  11. // 假设以下函数在其他地方实现,在此声明它们
  12. int findall_directory(int sockc);
  13. int download_directory(int sockc);
  14. int upload_directory(int sokc);
  15. int login(const char *user, const char *passwd);
  16. int regist(const char *user, const char *passwd);
  17. int logout(const char *user, const char *passwd);
  18. int  quit(const char *user);
  19. /*监听函数,返回监听套接字*/
  20. int mysock_init(const char *Ip, const char *Port)
  21. {
  22.     /* 1. 创建套接字*/
  23.     int sockl = socket(AF_INET, SOCK_STREAM, 0);
  24.     if (sockl == -1)
  25.         return -1;
  26.     /* 2. 绑定自己地址信息*/
  27.     struct sockaddr_in server = {0};
  28.     server.sin_family = AF_INET;
  29.     server.sin_port = htons(atoi(Port));
  30.     inet_pton(AF_INET, Ip, &server.sin_addr); //将字符串变成网络字节序
  31.     socklen_t len = sizeof(server);
  32.     if (-1 == bind(sockl, (struct sockaddr *)&server, len))
  33.     {
  34.         close(sockl);
  35.         return -1;
  36.     }
  37.     /* 3. 监听客户端连接*/
  38.     if (-1 == listen(sockl, 5))
  39.     {
  40.         close(sockl);
  41.         return -1;
  42.     }
  43.     //返回监听套接字
  44.     return sockl;
  45. }
  46. char user_name[20] = {0};
  47. /*连接函数,接收客户端连接*/
  48. int mysock_accept(int sockl)
  49. {
  50.     struct sockaddr_in peer = {0}; //对方
  51.     socklen_t len = sizeof(peer);
  52.     int sockc = accept(sockl, (struct sockaddr *)&peer, &len);
  53.     if (sockc == -1)
  54.         return -1;
  55.     char IP[INET_ADDRSTRLEN + 1];
  56.     inet_ntop(AF_INET, &peer.sin_addr, IP, INET_ADDRSTRLEN);
  57.     printf("[%s:%d]已连接\n", IP, ntohs(peer.sin_port));
  58.     //生成连接套接字
  59.     return sockc;
  60. }
  61. /* 接收客户端信息的函数*/
  62. void *from_client(void *argp)
  63. {
  64.     int sockc = *(int *)argp;
  65.     struct sockaddr_in peer = {0};
  66.     socklen_t len = sizeof(peer);
  67.     getpeername(sockc, (struct sockaddr *)&peer, &len);
  68.     // 获取客户端地址信息
  69.     while (1)
  70.     {
  71.         char str[512] = {0};
  72.         int n = recv(sockc, str, sizeof(str), 0);
  73.         if (n == 0)
  74.         {
  75.             printf("客户端[%s:%d]已断开连接\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
  76.             quit(user_name);
  77.             break;
  78.         }
  79.         /* 处理客户端请求*/
  80.         to_client(str, sockc);
  81.     }
  82.     return NULL;
  83. }
  84. void to_client(const char *jsStr, int sockc)
  85. {
  86.     /* 给客户端发消息*/
  87.     cJSON *root = cJSON_Parse(jsStr);
  88.     if (root == NULL)
  89.         return;
  90.     cJSON *itemRequest = cJSON_GetObjectItem(root, "request");
  91.     cJSON *itemUser = cJSON_GetObjectItem(root, "user");
  92.     cJSON *itemPasswd = cJSON_GetObjectItem(root, "passwd");
  93.    
  94.     //登录
  95.     if (strcmp(itemRequest->valuestring, "login") == 0)
  96.     {
  97.         puts("用户登录");
  98.         char *res[] = {"登录失败!", "登录成功!"};
  99.         int i = login(itemUser->valuestring, itemPasswd->valuestring);
  100.         cJSON *rever = cJSON_CreateObject();
  101.         if (rever == NULL)
  102.             return;
  103.         if (i == 1)
  104.         {
  105.             memset(user_name, 0, 20);
  106.             strcpy(user_name, itemUser->valuestring);
  107.         }
  108.         cJSON_AddStringToObject(rever, "rever", res[i]);
  109.         char *JSstr1 = cJSON_PrintUnformatted(rever);
  110.         send(sockc, JSstr1, strlen(JSstr1), 0);
  111.         cJSON_Delete(rever);
  112.     }
  113.     //注册
  114.     else if (strcmp(itemRequest->valuestring, "register") == 0)
  115.     {
  116.         puts("用户注册");
  117.         char *res[] = {"注册失败!", "注册成功,请登录..."};
  118.         int i = regist(itemUser->valuestring, itemPasswd->valuestring);
  119.         cJSON *rever = cJSON_CreateObject();
  120.         if (rever == NULL)
  121.             return;
  122.         cJSON_AddStringToObject(rever, "rever", res[i]);
  123.         char *JSstr1 = cJSON_PrintUnformatted(rever);
  124.         send(sockc, JSstr1, strlen(JSstr1), 0);
  125.         cJSON_Delete(rever);
  126.     }
  127.     //注销
  128.     else if (strcmp(itemRequest->valuestring, "logout") == 0)
  129.     {
  130.         puts("用户注销");
  131.         char *res[] = {"注销失败!", "注销成功!"};
  132.         int i = logout(itemUser->valuestring, itemPasswd->valuestring);
  133.         cJSON *rever = cJSON_CreateObject();
  134.         if (rever == NULL)
  135.             return;
  136.         cJSON_AddStringToObject(rever, "rever", res[i]);
  137.         char *JSstr1 = cJSON_PrintUnformatted(rever);
  138.         send(sockc, JSstr1, strlen(JSstr1), 0);
  139.         cJSON_Delete(rever);
  140.     }
  141.     // 浏览所有目录文件信息
  142.     else if (strcmp(itemRequest->valuestring, "findall_directory") == 0)
  143.     {
  144.         puts("浏览所有目录文件信息");
  145.         findall_directory(sockc);
  146.     }
  147.     // 上传目录文件信息
  148.     else if (strcmp(itemRequest->valuestring, "upload_directory") == 0)
  149.     {
  150.         puts("上传目录文件信息");
  151.         int upload_directory(int sockc) {
  152.             cJSON *root = cJSON_CreateObject();
  153.             cJSON *array = cJSON_CreateArray();
  154.             DIR *dir = opendir(".");
  155.             if (dir == NULL) {
  156.                 perror("opendir");
  157.                 cJSON_AddStringToObject(root, "reverse", "null");
  158.                 char *JSstr = cJSON_PrintUnformatted(root);
  159.                 send(sockc, JSstr, strlen(JSstr), 0);
  160.                 cJSON_Delete(root);
  161.                 free(JSstr);
  162.                 return -1;
  163.             }
  164.             struct dirent *entry;
  165.             while ((entry = readdir(dir))!= NULL) {
  166.                 if (entry->d_name[0] == '.') continue;
  167.                 struct stat st;
  168.                 if (stat(entry->d_name, &st) == -1) {
  169.                     perror("stat");
  170.                     continue;
  171.                 }
  172.                 cJSON *obj = cJSON_CreateObject();
  173.                 cJSON_AddStringToObject(obj, "name", entry->d_name);
  174.                 cJSON_AddNumberToObject(obj, "size", (int)st.st_size);
  175.                 cJSON_AddStringToObject(obj, "type", S_ISDIR(st.st_mode)? "directory" : "file");
  176.                 cJSON_AddItemToArray(array, obj);
  177.             }
  178.             closedir(dir);
  179.             cJSON_AddItemToObject(root, "data", array);
  180.             cJSON_AddStringToObject(root, "request", "upload_directory");
  181.             char *JSstr = cJSON_PrintUnformatted(root);
  182.             send(sockc, JSstr, strlen(JSstr), 0);
  183.             cJSON_Delete(root);
  184.             free(JSstr);
  185.             return 0;
  186.         }
  187.         upload_directory(sockc);
  188.     }
  189.     // 下载所有目录信息
  190.     else if (strcmp(itemRequest->valuestring, "download_directory") == 0)
  191.     {
  192.         puts("下载所有目录信息");
  193.         // 假设 download_directory 函数的参数为 sockc
  194.         download_directory(sockc);
  195.     }
  196.     //检测是否退出
  197.     else if (strcmp(itemRequest->valuestring, "quit") == 0)
  198.     {
  199.         quit(user_name);
  200.     }
  201.     //心跳检测机制
  202.     else if (strcmp(itemRequest->valuestring, "heartbeat") == 0)
  203.     {
  204.         struct sockaddr_in peer = {0}; //对方
  205.         socklen_t len = sizeof(peer);
  206.         getpeername(sockc, (struct sockaddr *)&peer, &len);
  207.         char IP[INET_ADDRSTRLEN + 1];
  208.         inet_ntop(AF_INET, &peer.sin_addr, IP, INET_ADDRSTRLEN);
  209.         printf("[%s:%d]还在连接中\n", IP, ntohs(peer.sin_port));
  210.     }
  211.     cJSON_Delete(root);
  212. }
复制代码
服务器端 server.c
  1. #include "myfun.h"
  2. #include "mysock.h"
  3. #include "pthreadpool.h"
  4. int main(int argc,char **argv)
  5. {
  6.     if(argc < 3)
  7.     {
  8.         fprintf(stderr,"Usage <%s SERIP SERPOST>\n",argv[0]);
  9.         return -1;
  10.     }
  11.     //调用函数
  12.     threadpool_t pool;
  13.     threadpool_init(&pool,8,10);
  14.     /* 1. 调用监听函数*/
  15.     int sockl = mysock_init(argv[1],argv[2]);
  16.     if(sockl == -1)
  17.     {
  18.         perror("mysock_init");
  19.         return -1;
  20.     }
  21.    
  22.     while(1)
  23.     {
  24.         /* 2.调用连接函数,接收客户端连接*/
  25.         int sockc = mysock_accept(sockl);
  26.         if(sockc == -1)
  27.             continue;
  28.             
  29.         threadpool_addtask(&pool,from_client,(void*)(uint64_t)sockc);
  30.     }
  31.     return 0;
  32. }
复制代码
服务器pthreadPool.c
  1. #include "pthreadpool.h"
  2. #include <stdlib.h>
  3. void* thread_fun(void *argp)
  4. {
  5.     threadpool_t* pool = (threadpool_t*)argp;
  6.     task_t    *p = NULL;
  7.     while(1)
  8.     {
  9.         //互斥锁
  10.         pthread_mutex_lock(&pool->mutex);
  11.         //判断队列情况
  12.         //任务队列为空等待
  13.         while(pool -> queue_num == 0)
  14.             pthread_cond_wait(&pool->queue_empty,&pool->mutex);
  15.         //任务队列不为空,被线程池中线程竞争
  16.         p = pool -> head;
  17.         pool -> queue_num--;
  18.         //表示任务队列只有一个节点
  19.         if(pool -> queue_num == 0)
  20.             pool -> head = pool -> tail = NULL;
  21.         else
  22.             pool -> head = p -> next;
  23.         //判断任务队列是否为满通知其他线程
  24.         if(pool->queue_num == pool -> queue_max_size -1)
  25.             pthread_cond_signal(&pool->queue_full);
  26.         pthread_mutex_unlock(&pool->mutex);
  27.         //调用函数
  28.         (*(p -> taskfun))(p -> argp);
  29.         //调用完毕回收资源
  30.         free(p);
  31.         p = NULL;
  32.     }
  33. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表