后台代码实现

  • 我的文件列表
    • Mian
    • 读取配置信息
    • 解析json登录token(cmd为count)
    • 解析jason(cmd不为count)
    • 获取用户文件个数
    • 获取用户文件列表
    • 源码
  • 共享文件列表
    • main
    • 获取共享文件个数
    • 前端分页请求包
    • 获得普通共享文件列表
    • 共享文件排行榜
    • 源码

我的文件列表

  • 业务逻辑是,点击我的文件,会在展示界面展示出该用户所有文件
  • 单机图标会显示选项下载,分享,删除,属性
  • 单机空白处会显示选型,会显示选项:按下载量排序/按下载量排序/刷新/上传
  • 其中上传操作也可以点击界面中的上传图标,然后会弹出窗口选择要上传的文件,上传过程是一个toolbar会显示进度在传输列表中

  • 实质是两张表联查 file_info, user_file_list ,做了物理分页,根据指令按照pv字段做升序降序排列

Mian

  • 读取配置文件 read_cfg();拿到数据库连接

  • while (FCGI_Accept() >= 0)等待连接

  • 业务主要分两种,一是只想知道用户有多少个文件,另一个是普通排序,按照pv升降序排序;均为post请求;为post请求时,由环境变量cmd拿到请求指令,由buf缓冲区拿到数据

  • cmd为count,获取用户文件个数if (strcmp(cmd, “count”) == 0) ,查表 get_user_files_count(user, ret); //获取用户文件个数

  • cmd为normal;pvacs;pvdesc;获取用户文件列表 get_user_filelist(cmd, user, start, count);

  • 需要注意的是,在fcgi程序中,直接fread是从标准输入读,就是从web服务器读;直接printf就是往标准输出,也是往web服务器(cgi程序利用I.O重定向技术)

          int main(){//count 获取用户文件个数//display 获取用户文件信息,展示到前端char cmd[20];char user[USER_NAME_LEN];char token[TOKEN_LEN];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);char *contentLength = getenv("CONTENT_LENGTH");int len;printf("Content-type: text/html\r\n\r\n");if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_count_json_info(buf, user, token); //通过json包获取用户名, token//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hget_user_files_count(user, ret); //获取用户文件个数}//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescelse{int start; //文件起点int count; //文件个数get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hif(ret == 0){get_user_filelist(cmd, user, start, count); //获取用户文件列表}else{char *out = return_status("111"); //token验证失败错误码if(out != NULL){printf(out); //给前端反馈错误码free(out);}}}}}return 0;}
    

读取配置信息

  • 读取到MySQL配置文件信息

      void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息//get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);//get_cfg_value(CFG_PATH, "redis", "port", redis_port);//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}
    

解析json登录token(cmd为count)

  • cmd为count时,此时的json包格式为

      {"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}
    
  • 此时,解析jason拿到token和username

      //解析的json包, 登陆tokenint get_count_json_info(char *buf, char *user, char *token){int ret = 0;/*json数据如下{"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//登陆tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);strcpy(token, child2->valuestring); //拷贝内容END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

解析jason(cmd不为count)

  • 作用是为了拿到user,token,start,count,用来给普通/升/降序同时物理分页查询准备

          //解析的json包int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count){int ret = 0;/*json数据如下{"user": "yoyo""token": xxxx"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}strcpy(token, child2->valuestring); //拷贝内容//文件起点cJSON *child3 = cJSON_GetObjectItem(root, "start");if(NULL == child3){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child3->valueint;//文件请求个数cJSON *child4 = cJSON_GetObjectItem(root, "count");if(NULL == child4){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child4->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

获取用户文件个数

  • 数据库查询操作 sprintf(sql_cmd, “select count from user_file_count where user=”%s"", user);

  • 将结果封装进tmp int ret2 = process_result_one(conn, sql_cmd, tmp);

          //获取用户文件个数void get_user_files_count(char *user, int ret){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);char tmp[512] = {0};//返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);//给前端反馈的信息return_login_status(line, ret);}
    

    获取用户文件列表

  • get_user_filelist(char *cmd, char *user, int start, int count)需要参数cmd,user,start,count(这两个参数在前端设置好)

      - cmd为normal 普通查询只做了物理分页,==limit %d, %d", user, start, count==if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}  - cmd为pvasc升序查询按照pv排序同时做了物理分页,==order by pv asc limit %d, %d", user, start, count)==else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}-  cmd为pvdesc降序查询按照pv排序同时做了物理分页,==order by pv desc limit %d, %d", user, start, count==else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}
    
  • 进行查询 if (mysql_query(conn, sql_cmd) != 0)

  • 生成结果集 res_set = mysql_store_result(conn);/生成结果集/

  • 对结果集进行处理

    • 数据库的查询结果是一行行的,游标依次往下拿到每一个字段的值,封装进jason对象 cJSON_AddItemToArray(array, item);
    • 再封装进数组cJSON_AddItemToObject(root, “files”, array)代表所有文件的列表,
    • 再将该数组封装进root根对象转为字符串发送前端
      int get_user_filelist(char *cmd, char *user, int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//多表指定行范围查询if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0)//没有结果{LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 0,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user 文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享if(row[4] != NULL){cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));}//-- pv 文件下载量,默认值为0,下载一次加1if(row[5] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[5] ));}//-- url 文件urlif(row[6] != NULL){cJSON_AddStringToObject(item, "url", row[6]);}//-- size 文件大小, 以字节为单位if(row[7] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[7] ));}//-- type 文件类型: png, zip, mp4……if(row[8] != NULL){cJSON_AddStringToObject(item, "type", row[8]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败/*获取用户文件列表:成功:文件列表json失败:{"code": "015"}*/out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}
    

源码

 /*** @file myfiles_cgi.c* @brief  用户列表展示CGI程序* @author Mike* @version 2.0* @date 2017年2月27日*/#include "fcgi_config.h"#include "fcgi_stdio.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "make_log.h" //日志头文件#include "util_cgi.h"#include "deal_mysql.h"#include "cfg.h"#include "cJSON.h"#include <sys/time.h>#define MYFILES_LOG_MODULE       "cgi"#define MYFILES_LOG_PROC         "myfiles"//mysql 数据库配置信息 用户名, 密码, 数据库名称static char mysql_user[128] = {0};static char mysql_pwd[128] = {0};static char mysql_db[128] = {0};//redis 服务器ip、端口//static char redis_ip[30] = {0};//static char redis_port[10] = {0};//读取配置信息void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息//get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);//get_cfg_value(CFG_PATH, "redis", "port", redis_port);//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}//解析的json包, 登陆tokenint get_count_json_info(char *buf, char *user, char *token){int ret = 0;/*json数据如下{"token": "9e894efc0b2a898a82765d0a7f2c94cb",user:xxxx}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//登陆tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child2->valuestring = %s\n", child2->valuestring);strcpy(token, child2->valuestring); //拷贝内容END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//返回前端情况void return_login_status(long num, int token_flag){char *out = NULL;char *token;char num_buf[128] = {0};if(token_flag == 0){token = "110"; //成功}else{token = "111"; //失败}//数字sprintf(num_buf, "%ld", num);cJSON *root = cJSON_CreateObject();  //创建json项目cJSON_AddStringToObject(root, "num", num_buf);// {"num":"1111"}cJSON_AddStringToObject(root, "code", token);// {"code":"110"}out = cJSON_Print(root);//cJSON to string(char *)cJSON_Delete(root);if(out != NULL){printf(out); //给前端反馈信息free(out); //记得释放}}//获取用户文件个数void get_user_files_count(char *user, int ret){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", user);char tmp[512] = {0};//返回值: 0成功并保存记录集,1没有记录集,2有记录集但是没有保存,-1失败int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "line = %ld\n", line);//给前端反馈的信息return_login_status(line, ret);}//解析的json包int get_fileslist_json_info(char *buf, char *user, char *token, int *p_start, int *p_count){int ret = 0;/*json数据如下{"user": "yoyo""token": xxxx"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//返回指定字符串对应的json对象//用户cJSON *child1 = cJSON_GetObjectItem(root, "user");if(NULL == child1){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}//LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "child1->valuestring = %s\n", child1->valuestring);strcpy(user, child1->valuestring); //拷贝内容//tokencJSON *child2 = cJSON_GetObjectItem(root, "token");if(NULL == child2){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}strcpy(token, child2->valuestring); //拷贝内容//文件起点cJSON *child3 = cJSON_GetObjectItem(root, "start");if(NULL == child3){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child3->valueint;//文件请求个数cJSON *child4 = cJSON_GetObjectItem(root, "count");if(NULL == child4){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child4->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//获取用户文件列表//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescint get_user_filelist(char *cmd, char *user, int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//多表指定行范围查询if(strcmp(cmd, "normal") == 0) //获取用户文件信息{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvasc") == 0) //按下载量升序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5  order by pv asc limit %d, %d", user, start, count);}else if(strcmp(cmd, "pvdesc") == 0) //按下载量降序{//sql语句sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s 操作失败:%s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "smysql_store_result error: %s!\n", mysql_error(conn));ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0)//没有结果{LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "mysql_num_rows(res_set) failed:%s\n", mysql_error(conn));ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 0,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user    文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享if(row[4] != NULL){cJSON_AddNumberToObject(item, "share_status", atoi( row[4] ));}//-- pv 文件下载量,默认值为0,下载一次加1if(row[5] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[5] ));}//-- url 文件urlif(row[6] != NULL){cJSON_AddStringToObject(item, "url", row[6]);}//-- size 文件大小, 以字节为单位if(row[7] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[7] ));}//-- type 文件类型: png, zip, mp4……if(row[8] != NULL){cJSON_AddStringToObject(item, "type", row[8]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败/*获取用户文件列表:成功:文件列表json失败:{"code": "015"}*/out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}int main(){//count 获取用户文件个数//display 获取用户文件信息,展示到前端char cmd[20];char user[USER_NAME_LEN];char token[TOKEN_LEN];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "cmd = %s\n", cmd);char *contentLength = getenv("CONTENT_LENGTH");int len;printf("Content-type: text/html\r\n\r\n");if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "buf = %s\n", buf);if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_count_json_info(buf, user, token); //通过json包获取用户名, token//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hget_user_files_count(user, ret); //获取用户文件个数}//获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal//按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc//按下载量降序127.0.0.1:80/myfiles?cmd=pvdescelse{int start; //文件起点int count; //文件个数get_fileslist_json_info(buf, user, token, &start, &count); //通过json包获取信息LOG(MYFILES_LOG_MODULE, MYFILES_LOG_PROC, "user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);//验证登陆token,成功返回0,失败-1ret = verify_token(user, token); //util_cgi.hif(ret == 0){get_user_filelist(cmd, user, start, count); //获取用户文件列表}else{char *out = return_status("111"); //token验证失败错误码if(out != NULL){printf(out); //给前端反馈错误码free(out);}}}}}return 0;}

共享文件列表

业务逻辑,点击QT界面的共享列表,会显示背当前用户共享的文件,且是普通排序

  • 点击图标会显示取消分享,属性
  • 点击空白处会选项显示排行榜

共享文件列表主要涉及的是file_info和share_file_list两张表查询

main

  • cmd为count,代表获取该用户共享出去的文件个数,只返回给前端共享了的文件个数

       if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_share_files_count(); //获取共享文件个数}
    
  • 解析jason包拿到拿到count,start

  • 如果cmd为normal,则就按照查询顺序显示共享文件列表

  • 如果cmd为pvdesc,则将查询结果按照pv字段降序排列显示共享文件列表

  • 如果cmd为pvasc,则将查询结果按照pv字段升序排列显示为共享文件列表

获取共享文件个数

  • get_share_files_count(),当cmd为count,则只需要查询共享文件个数

  • 从user_file_count查询处用户的共享文件个数

     void get_share_files_count(){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");char tmp[512] = {0};int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);printf("%ld", line); //给前端反馈的信息}

前端分页请求包

  • get_fileslist_json_info

  • 这个包是前端发送的post数据,封装的是物理分页的信息,然后再根据URL上的指令去做业务逻辑判断

  • 解析包拿到start,count

      //解析的json包int get_fileslist_json_info(char *buf, int *p_start, int *p_count){int ret = 0;/*json数据如下{"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//文件起点cJSON *child2 = cJSON_GetObjectItem(root, "start");if(NULL == child2){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child2->valueint;//文件请求个数cJSON *child3 = cJSON_GetObjectItem(root, "count");if(NULL == child3){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child3->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}
    

获得普通共享文件列表

  • get_share_filelist(int start, int count)

  • 查出share_file_list所有记录,同时根据md5查file_info表部分文件信息并进行物理分页

  • 从结果集中将记录进行一行行封装成对象;将封装好的对象加入数组;将数组加到跟对象root,将root转为字符串输出

      //获取共享文件列表//获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normalint get_share_filelist(int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//sql语句sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 1,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user   文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享cJSON_AddNumberToObject(item, "share_status", 1);//-- pv 文件下载量,默认值为0,下载一次加1if(row[4] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[4] ));}//-- url 文件urlif(row[5] != NULL){cJSON_AddStringToObject(item, "url", row[5]);}//-- size 文件大小, 以字节为单位if(row[6] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[6] ));}//-- type 文件类型: png, zip, mp4……if(row[7] != NULL){cJSON_AddStringToObject(item, "type", row[7]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}
    

共享文件排行榜

  • 操作redis “FILE_NAME_HASH”和“FILE_PUBLIC_ZSET”两张表和MySQL“share_file_list”,完成redis和MySQL数据交互
  • int get_ranking_filelist(int start, int count)
  • 拿到mysql中共享文件的数量,拿到redis中的共享文件的数量进行比较
    • 不相等,更新redis数据,删除redis中所有数据( FILE_PUBLIC_ZSET,FILE_NAME_HASH) ;再将mysql中的数据导入到mysql:查出share_file_list中md5,filename和pv字段,游标提取结果集每一行(md5+filename组成fileid和pv字段作为score一起添加到zset;将组合的fileid作为fileld,filename作为value添加到hash表)
  • 将zset按照score降序排序,其中排序有分页参数start,end;
  • 将排序后的集合从FILE_NAME_HASH取出filename,从FILE_PUBLIC_ZSET取出pv字段封装成对象;再将数据封装成对象转字符串后发送给前端 printf("%s", out),会在QT界面点击排行榜时候显示

源码

 /*** @file sharefiles_cgi.c* @brief  共享文件列表展示CGI程序* @author Mike* @version 2.0* @date 2017年3月7日21:46:57*/#include "fcgi_config.h"#include "fcgi_stdio.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "make_log.h" //日志头文件#include "util_cgi.h"#include "deal_mysql.h"#include "redis_keys.h"#include "redis_op.h"#include "cfg.h"#include "cJSON.h"#include <sys/time.h>#define SHAREFILES_LOG_MODULE       "cgi"#define SHAREFILES_LOG_PROC         "sharefiles"//mysql 数据库配置信息 用户名, 密码, 数据库名称static char mysql_user[128] = {0};static char mysql_pwd[128] = {0};static char mysql_db[128] = {0};//redis 服务器ip、端口static char redis_ip[30] = {0};static char redis_port[10] = {0};//读取配置信息void read_cfg(){//读取mysql数据库配置信息get_cfg_value(CFG_PATH, "mysql", "user", mysql_user);get_cfg_value(CFG_PATH, "mysql", "password", mysql_pwd);get_cfg_value(CFG_PATH, "mysql", "database", mysql_db);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql:[user=%s,pwd=%s,database=%s]", mysql_user, mysql_pwd, mysql_db);//读取redis配置信息get_cfg_value(CFG_PATH, "redis", "ip", redis_ip);get_cfg_value(CFG_PATH, "redis", "port", redis_port);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis:[ip=%s,port=%s]\n", redis_ip, redis_port);}//获取共享文件个数void get_share_files_count(){char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;long line = 0;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");char tmp[512] = {0};int ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);goto END;}line = atol(tmp); //字符串转长整形END:if(conn != NULL){mysql_close(conn);}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "line = %ld\n", line);printf("%ld", line); //给前端反馈的信息}//解析的json包int get_fileslist_json_info(char *buf, int *p_start, int *p_count){int ret = 0;/*json数据如下{"start": 0"count": 10}*///解析json包//解析一个json字符串为cJSON对象cJSON * root = cJSON_Parse(buf);if(NULL == root){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_Parse err\n");ret = -1;goto END;}//文件起点cJSON *child2 = cJSON_GetObjectItem(root, "start");if(NULL == child2){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_start = child2->valueint;//文件请求个数cJSON *child3 = cJSON_GetObjectItem(root, "count");if(NULL == child3){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cJSON_GetObjectItem err\n");ret = -1;goto END;}*p_count = child3->valueint;END:if(root != NULL){cJSON_Delete(root);//删除json对象root = NULL;}return ret;}//获取共享文件列表//获取用户文件信息 127.0.0.1:80/sharefiles&cmd=normalint get_share_filelist(int start, int count){int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;MYSQL_RES *res_set = NULL;//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//sql语句sprintf(sql_cmd, "select share_file_list.*, file_info.url, file_info.size, file_info.type from file_info, share_file_list where file_info.md5 = share_file_list.md5 limit %d, %d", start, count);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;root = cJSON_CreateObject();array = cJSON_CreateArray();// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//array[i]:cJSON* item = cJSON_CreateObject();//mysql_num_fields获取结果中列的个数/*for(i = 0; i < mysql_num_fields(res_set); i++){if(row[i] != NULL){}}*//*{"user": "yoyo","md5": "e8ea6031b779ac26c319ddf949ad9d8d","time": "2017-02-26 21:35:25","filename": "test.mp4","share_status": 1,"pv": 0,"url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4","size": 27473666,"type": "mp4"}*///-- user 文件所属用户if(row[0] != NULL){cJSON_AddStringToObject(item, "user", row[0]);}//-- md5 文件md5if(row[1] != NULL){cJSON_AddStringToObject(item, "md5", row[1]);}//-- createtime 文件创建时间if(row[2] != NULL){cJSON_AddStringToObject(item, "time", row[2]);}//-- filename 文件名字if(row[3] != NULL){cJSON_AddStringToObject(item, "filename", row[3]);}//-- shared_status 共享状态, 0为没有共享, 1为共享cJSON_AddNumberToObject(item, "share_status", 1);//-- pv 文件下载量,默认值为0,下载一次加1if(row[4] != NULL){cJSON_AddNumberToObject(item, "pv", atol( row[4] ));}//-- url 文件urlif(row[5] != NULL){cJSON_AddStringToObject(item, "url", row[5]);}//-- size 文件大小, 以字节为单位if(row[6] != NULL){cJSON_AddNumberToObject(item, "size", atol( row[6] ));}//-- type 文件类型: png, zip, mp4……if(row[7] != NULL){cJSON_AddStringToObject(item, "type", row[7]);}cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(conn != NULL){mysql_close(conn);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}//获取共享文件排行版//按下载量降序127.0.0.1:80/sharefiles?cmd=pvdescint get_ranking_filelist(int start, int count){/*a) mysql共享文件数量和redis共享文件数量对比,判断是否相等b) 如果不相等,清空redis数据,从mysql中导入数据到redis (mysql和redis交互)c) 从redis读取数据,给前端反馈相应信息*/int ret = 0;char sql_cmd[SQL_MAX_LEN] = {0};MYSQL *conn = NULL;cJSON *root = NULL;RVALUES value = NULL;cJSON *array =NULL;char *out = NULL;char *out2 = NULL;char tmp[512] = {0};int ret2 = 0;MYSQL_RES *res_set = NULL;redisContext * redis_conn = NULL;//连接redis数据库redis_conn = rop_connectdb_nopwd(redis_ip, redis_port);if (redis_conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "redis connected error");ret = -1;goto END;}//connect the databaseconn = msql_conn(mysql_user, mysql_pwd, mysql_db);if (conn == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "msql_conn err\n");ret = -1;goto END;}//设置数据库编码,主要处理中文编码问题mysql_query(conn, "set names utf8");//===1、mysql共享文件数量sprintf(sql_cmd, "select count from user_file_count where user=\"%s\"", "xxx_share_xxx_file_xxx_list_xxx_count_xxx");ret2 = process_result_one(conn, sql_cmd, tmp); //指向sql语句if(ret2 != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败\n", sql_cmd);ret = -1;goto END;}int sql_num = atoi(tmp); //字符串转长整形//===2、redis共享文件数量int redis_num = rop_zset_zcard(redis_conn, FILE_PUBLIC_ZSET);if(redis_num == -1){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zcard 操作失败\n");ret = -1;goto END;}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "sql_num = %d, redis_num = %d\n", sql_num, redis_num);//===3、mysql共享文件数量和redis共享文件数量对比,判断是否相等if(redis_num != sql_num){//===4、如果不相等,清空redis数据,重新从mysql中导入数据到redis (mysql和redis交互)//a) 清空redis有序数据rop_del_key(redis_conn, FILE_PUBLIC_ZSET);rop_del_key(redis_conn, FILE_NAME_HASH);//b) 从mysql中导入数据到redis//sql语句strcpy(sql_cmd, "select md5, filename, pv from share_file_list order by pv desc");LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 在操作\n", sql_cmd);if (mysql_query(conn, sql_cmd) != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s 操作失败: %s\n", sql_cmd, mysql_error(conn));ret = -1;goto END;}res_set = mysql_store_result(conn);/*生成结果集*/if (res_set == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "smysql_store_result error!\n");ret = -1;goto END;}ulong line = 0;//mysql_num_rows接受由mysql_store_result返回的结果结构集,并返回结构集中的行数line = mysql_num_rows(res_set);if (line == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_num_rows(res_set) failed\n");ret = -1;goto END;}MYSQL_ROW row;// mysql_fetch_row从使用mysql_store_result得到的结果结构中提取一行,并把它放到一个行结构中。// 当数据用完或发生错误时返回NULL.while ((row = mysql_fetch_row(res_set)) != NULL){//md5, filename, pvif(row[0] == NULL || row[1] == NULL || row[2] == NULL){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "mysql_fetch_row(res_set)) failed\n");ret = -1;goto END;}char fileid[1024] = {0};sprintf(fileid, "%s%s", row[0], row[1]); //文件标示,md5+文件名//增加有序集合成员rop_zset_add(redis_conn, FILE_PUBLIC_ZSET, atoi(row[2]), fileid);//增加hash记录rop_hash_set(redis_conn, FILE_NAME_HASH, fileid, row[1]);}}//===5、从redis读取数据,给前端反馈相应信息//char value[count][1024];value  = (RVALUES)calloc(count, VALUES_ID_SIZE); //堆区请求空间if(value == NULL){ret = -1;goto END;}int n = 0;int end = start + count - 1;//加载资源的结束位置//降序获取有序集合的元素ret = rop_zset_zrevrange(redis_conn, FILE_PUBLIC_ZSET, start, end, value, &n);if(ret != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_zrevrange 操作失败\n");goto END;}root = cJSON_CreateObject();array = cJSON_CreateArray();//遍历元素个数for(int i = 0; i < n; ++i){//array[i]:cJSON* item = cJSON_CreateObject();/*{"filename": "test.mp4","pv": 0}*///-- filename 文件名字char filename[1024] = {0};ret = rop_hash_get(redis_conn, FILE_NAME_HASH, value[i], filename);if(ret != 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_hash_get 操作失败\n");ret = -1;goto END;}cJSON_AddStringToObject(item, "filename", filename);//-- pv 文件下载量int score = rop_zset_get_score(redis_conn, FILE_PUBLIC_ZSET, value[i]);if(score == -1){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "rop_zset_get_score 操作失败\n");ret = -1;goto END;}cJSON_AddNumberToObject(item, "pv", score);cJSON_AddItemToArray(array, item);}cJSON_AddItemToObject(root, "files", array);out = cJSON_Print(root);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "%s\n", out);END:if(ret == 0){printf("%s", out); //给前端反馈信息}else{   //失败out2 = NULL;out2 = return_status("015");}if(out2 != NULL){printf(out2); //给前端反馈错误码free(out2);}if(res_set != NULL){//完成所有对数据的操作后,调用mysql_free_result来善后处理mysql_free_result(res_set);}if(redis_conn != NULL){rop_disconnect(redis_conn);}if(conn != NULL){mysql_close(conn);}if(value != NULL){free(value);}if(root != NULL){cJSON_Delete(root);}if(out != NULL){free(out);}return ret;}int main(){char cmd[20];//读取数据库配置信息read_cfg();//阻塞等待用户连接while (FCGI_Accept() >= 0){// 获取URL地址 "?" 后面的内容char *query = getenv("QUERY_STRING");//解析命令query_parse_key_value(query, "cmd", cmd, NULL);LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "cmd = %s\n", cmd);printf("Content-type: text/html\r\n\r\n");if (strcmp(cmd, "count") == 0) //count 获取用户文件个数{get_share_files_count(); //获取共享文件个数}else{char *contentLength = getenv("CONTENT_LENGTH");int len;if( contentLength == NULL ){len = 0;}else{len = atoi(contentLength); //字符串转整型}if (len <= 0){printf("No data from standard input.<p>\n");LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "len = 0, No data from standard input\n");}else{char buf[4*1024] = {0};int ret = 0;ret = fread(buf, 1, len, stdin); //从标准输入(web服务器)读取内容if(ret == 0){LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "fread(buf, 1, len, stdin) err\n");continue;}LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "buf = %s\n", buf);//获取共享文件信息 127.0.0.1:80/sharefiles&cmd=normal//按下载量升序 127.0.0.1:80/sharefiles?cmd=pvasc//按下载量降序127.0.0.1:80/sharefiles?cmd=pvdescint start; //文件起点int count; //文件个数get_fileslist_json_info(buf, &start, &count); //通过json包获取信息LOG(SHAREFILES_LOG_MODULE, SHAREFILES_LOG_PROC, "start = %d, count = %d\n", start, count);if (strcmp(cmd, "normal") == 0){get_share_filelist(start, count); //获取共享文件列表}else if(strcmp(cmd, "pvdesc") == 0){get_ranking_filelist(start, count);//获取共享文件排行版}}}}return 0;}

[云盘](二)我的文件和共享列表后台实现相关推荐

  1. 天翼云盘目录索引php,如何设置天翼云盘同步目录与文件?天翼云盘同步目录与文件的方法...

    如何设置天翼云盘同步目录与文件?有的用户还不是很熟悉,下文就是小编给大家分享天翼云盘同步目录与文件的方法,希望对你们有所帮助哦. 1.用户在首次登陆天翼云PC客户端时,客户端会为用户弹出文件同步设置窗 ...

  2. 基于阿里云盘二次开发实现磁盘同步,双向同步

    基于阿里云盘实现磁盘同步 最近也是研究了一下阿里云盘也是把网盘的各种协议,在python上实现了一遍,也是大概了解了一些阿里在某些方面是如何处理的,比如:如何避免网盘数据泄露.如何实现快传.大文件传输 ...

  3. 如何向天翼云服务器上传文件,天翼云盘如何上传文件?

    天翼云盘官方版是一个提供文件同步.备份及分享等服务的网络云存储平台.您可以通过网页.pc客户端及移动客户端随时随地的把照片.音乐.视频.文档等轻松地保存到网络,无须担心文件丢失.通过天翼云,多终端上传 ...

  4. 谷歌云盘Colaboratory如何载入文件

    谷歌云的Colaboratory的项目的确不错,提供Tesla K80这块高级的GPU加速功能,但是也存在一个问题. 因为Colaboratory是完全云端的,所以,每次如果想让他访问谷歌云盘的内容, ...

  5. Google Colab 读取/存储 google drive(谷歌云盘)内的文件

    当然使用个命令需要登录google账号 获取相应的验证码 将验证码复制到框内 回车即可继续执行 完整如下: import os from google.colab import drive drive ...

  6. CDA学习 之 MySQL - 通过阿里云盘整体迁移数据库文件

    目录 前言:需求 一.数据库文件备份到阿里云 1.1关闭本地MySQL服务 1.2单个库文件文件打包 1.3data目录打包 1.4重启MySQL80服务 1.5上传到阿里云 二.阿里云数据恢复到本机 ...

  7. OneDrive云盘使用

    OneDrive相对于百度云盘(1024G),天翼网盘(60G)等云盘,官方提供的磁盘空间仅为5G. 背景: 为了减少电脑本地的内存空间,以同步云盘,实现联机文件的共享和同步 准备: Win10默认是 ...

  8. 【软件应用开发】基于SSM框架的共享云盘系统设计与实现

    本文编写目的:描述共享云盘系统的实现功能.运行环境以及系统的使用说明. 共享云盘系统完整代码:https://download.csdn.net/download/weixin_47936614/86 ...

  9. 云服务器文件做共享,云服务器文件共享

    云服务器文件共享 内容精选 换一换 本节操作指导用户实现同一个子网的Windows弹性云服务器之间文件共享.共享文件的云服务器在同一个子网下,且网络互通.在云服务器右下方的网络图标处,右键单击&quo ...

最新文章

  1. jQuery自定义选择器
  2. 新东方面试知识点记录
  3. 通过编写串口助手工具学习MFC过程——(三)Unicode字符集的宽字符和多字节字符转换...
  4. html隐藏标签console,console的隐藏知识点,你get到了嘛?
  5. useragent大全
  6. FreeRTOS 教程指南 学习笔记 第五章 软件计时器
  7. eclipse adt bundle不显示Android SDK菜单
  8. 美通企业周刊 | 世界最长海底公路隧道在青海开工;乐高华南首家品牌旗舰店开业;洲际加速布局粤港澳大湾区...
  9. pandas 选择数据与条件筛选iloc/loc/filt
  10. 安装docker多系统操作示列(window为例)
  11. Android开发前景及现状分析,高级android工程师
  12. oracle中db_create_file_dest参数
  13. 新构造运动名词解释_第十三章 新构造运动
  14. Linux下几种定时器的使用
  15. sqlmap 使用方法
  16. 二、数码管显示原理及应用实现
  17. 用c语言编写小狗图形,小狗的图片简笔画
  18. 天啊!吃饭用的勺子都联网了~手把手带你DIY一款智能百味勺子
  19. 区块链思维—系统性思维
  20. 智简教育城域网,为教育创新铺路

热门文章

  1. Python科学计算:常微分方程2
  2. vs2022 配置大全——超完整版
  3. 虚拟机静态ip配置及vi编辑器的使用
  4. 3、住房贷款分公积金贷款和商业贷款,还款方式有等额本息还款和等额本金还款,贷款利率如下表所示。编写一程序,输入贷款总额、贷款类型和贷款年限,计算每期的还款额和总还款额。
  5. 安装polyglot出错
  6. 电脑录像软件哪个好用?录屏大神的技巧分享
  7. 你去面试,需要准备什么知识点?
  8. 认证班丨AQF量化金融分析师认证班火热报名中
  9. 优秀课程案例:使用Scratch的画笔积木绘制甲壳虫的七彩移动轨迹!
  10. 微信小程序-能左右滑动的订单列表