简单的网盘系统

        项目使用TCP搭建的高并发服务器,客户端根据服务器来写的相应功能来写,主要实现文件上传和文件下载。

开发环境:Linux系统中的Ubuntu

开发语言:C语言

编码软件:VScode

使用到的相关技术:使用sqlite3数据库保存用户信息和文件名,cJSON来进行数据的传递

项目中主要的文件夹,客户端和服务器都使用Makefile来管理,主要是好编译。

 下面附上服务器和客户端的主要编码,服务器端为守护进程,项目一般,其中如有没见过的宏和结构体,那就是在头文件中,如果需要其他可找我要

服务器中main.c

/*************************************************************************
> File Name:server
> Author: Lxx
> Created Time: 2023-03-01 13:52:48
> description: 网盘系统基于TCP的服务器端
> versions: 1.0
************************************************************************/
#include "server.h"

int main(int argc, const char *argv[])
{   
    //创建守护进程
    pid_t pid;

    pid = fork();
    if (-1 == pid) {
        ERRLOG("fork error");
    } else if (pid == 0) {
        int fd;
        // 1.产生了孤儿进程
        // 2.设置sid
        setsid();
        // 3.修改路径(修改了线程的工作路径)
        chdir("/home/student/network/server");
        // 4.重新设置掩码
        umask(0);
        //关闭已打开的从3开始所有的文件描述符
        int max = sysconf(_SC_OPEN_MAX);
        for (int i = 3; i < max; i++)
            close(i);
        // 5.打开日志文件
        if ((fd = open("syslog.log", O_RDWR | O_CREAT | O_APPEND, 0666)) == -1)
            ERRLOG("open error");
        // 6.重定向文件描述符
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        // 7.开启自己的服务
        while (1) {
            //创建流式套接字
            int sockfd1 = 0, sockfd2 = 0;
            if(-1 == (sockfd1 = socket(AF_INET, SOCK_STREAM, 0))){
                ERRLOG("sockfd error");
            }

            if(-1 == (sockfd2 = socket(AF_INET, SOCK_STREAM, 0))){
                ERRLOG("sockfd error");
            }
            //填充网络信息结构体
            struct sockaddr_in serveraddr = {0};
            serveraddr.sin_family = AF_INET;
            serveraddr.sin_port = htons(PORT1);
            serveraddr.sin_addr.s_addr = inet_addr(IP);
            //绑定
            if(-1 == bind(sockfd1, (struct sockaddr *)&serveraddr, sizeof(serveraddr))){
                ERRLOG("bind error");
            }
            serveraddr.sin_port = htons(PORT2);
            if(-1 == bind(sockfd2, (struct sockaddr *)&serveraddr, sizeof(serveraddr))){
                ERRLOG("bind error");
            }
            //监听
            if(-1 == listen(sockfd1, 10)){
                ERRLOG("listen error");
            }
            if(-1 == listen(sockfd2, 10)){
                ERRLOG("listen error");
            }

            //客户端结构体
            struct sockaddr_in clientaddr = {0};
            socklen_t clientaddr_len = sizeof(clientaddr);

            int acceptfd = 0;
            pthread_t pit1 = 0, pit2 = 0;
            time_t t = 0;
            struct tm *time_Temp = NULL;
            struct addr msg = {0};
            //创建两个进程
            if(fork() == 0){//负责简单功能
                //客户端连接
                
                while(1){
                    if(-1 == (acceptfd = accept(sockfd1, (struct sockaddr *)&clientaddr, &clientaddr_len))){
                        ERRLOG("accept error");
                    }

                    msg.clientaddr = clientaddr;
                    msg.cid = acceptfd;
                    //客户端连接时间
                    time(&t);
                    time_Temp = localtime(&t);
                    printf("%d年%d月%d日 %d时%d分%d秒:",time_Temp->tm_year+1900, 
                    time_Temp->tm_mon+1, time_Temp->tm_mday, time_Temp->tm_hour, time_Temp->tm_min,
                    time_Temp->tm_sec);
                    
                    printf("有[%s:%d]连接进来了\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                    fflush(stdout);
                    //一个客户端就创建一个线程
                    pthread_create(&pit1, NULL, pthread_func1, &msg);
                    //设置为分离态
                    pthread_detach(pit1);
                
                }
            }

            if(fork() == 0){//负责文件功能
                //客户端连接
                while(1){
                    if(-1 == (acceptfd = accept(sockfd2, (struct sockaddr *)&clientaddr, &clientaddr_len))){
                        ERRLOG("accept error");
                    }

                    
                    msg.clientaddr = clientaddr;
                    msg.cid = acceptfd;

                    time(&t);
                    time_Temp = localtime(&t);
                    printf("%d年%d月%d日 %d时%d分%d秒:",time_Temp->tm_year+1900, 
                    time_Temp->tm_mon+1, time_Temp->tm_mday, time_Temp->tm_hour, time_Temp->tm_min,
                    time_Temp->tm_sec);

                    printf("有[%s:%d]连接进来了\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                    fflush(stdout);
                    //一个客户端就创建一个线程
                    pthread_create(&pit2, NULL, pthread_func2, &msg);
                    //设置为分离态
                    pthread_detach(pit2);
                
                }
            }
            
            //关闭流式套接字
            close(sockfd1);
            close(sockfd2);

            //回收进程
            wait(NULL);
            wait(NULL);
        }

    } else {
        exit(0);
    }
    
    return 0;
}

server.c

#include "server.h"

void JSON_Parese1(int cid, cJSON *object);//解析基本功能
void JSON_Parese2(int cid, cJSON *object);//解析文件功能
static int insert_filename(char *filename, int act);//向数据库添加文件名
static int find_filename_exsit(char *filename, int act);//查找文件是否存在
static int use_password_compare(char *old_password, int act);//密码比较

/*****************************************************************************
功  能:客户线程函数,处理客户端普通功能
参  数:
    arg:客户套接字
****************************************************************************/
void *pthread_func1(void *arg){

    //接收发过来的客户端acceptfd
    struct addr msg = *(struct addr*)arg;
    //循环处理客户端消息
    char *buf = malloc(1024);
    int len = 0;
    time_t t = 0;
    struct tm *time_Temp = NULL;
    while (1)
    {
        memset(buf, 0, 1024);
        len = read(msg.cid, buf, 1024);
        if (len <= 0)
        {   
            time(&t);
            time_Temp = localtime(&t);
            printf("%d年%d月%d日 %d时%d分%d秒:",time_Temp->tm_year+1900, 
            time_Temp->tm_mon+1, time_Temp->tm_mday, time_Temp->tm_hour, time_Temp->tm_min,
            time_Temp->tm_sec);
            printf("有[%s:%d]断开连接\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port));
            fflush(stdout);
            break;
        }
        //printf("%s\n",buf);
        //处理客户端消息
        cJSON *object = cJSON_Parse(buf);
        if (object != NULL)
        {   
            //printf("%s\n", cJSON_Print(object));
            //功能处理
            JSON_Parese1(msg.cid, object);

            //回收JSON
            cJSON_Delete(object); 
        }
    }
    free(buf);
    close(msg.cid);
    pthread_exit(0);
}

/*****************************************************************************
功  能:处理文件文件功能
参  数:客户套接字
****************************************************************************/
void *pthread_func2(void *arg){

    //接收发过来的客户端acceptfd
    struct addr msg = *(struct addr*)arg;
    //循环处理客户端消息
    char *buf = malloc(1024);
    int len = 0;
    time_t t = 0;
    struct tm *time_Temp = NULL;
    while (1)
    {
        memset(buf, 0, 1024);
        len = read(msg.cid, buf, 1024);
        if (len <= 0)
        {
            time(&t);
            time_Temp = localtime(&t);
            printf("%d年%d月%d日 %d时%d分%d秒:",time_Temp->tm_year+1900, 
            time_Temp->tm_mon+1, time_Temp->tm_mday, time_Temp->tm_hour, time_Temp->tm_min,
            time_Temp->tm_sec);
            printf("有[%s:%d]断开连接\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port));
            fflush(stdout);
            break;
        }
        //printf("%s\n",buf);
        //处理客户端消息
        cJSON *object = cJSON_Parse(buf);
        if (object != NULL)
        {
            //printf("%s\n", cJSON_Print(object));
            //功能处理
            JSON_Parese2(msg.cid, object);

            //回收JSON
            cJSON_Delete(object); 
        }
    }
    free(buf);
    close(msg.cid);
    pthread_exit(0);
}

/*****************************************************************************
功  能:解析cJSON简单功能
参  数:
        acceptfd:用户套接字
        object:JSON
****************************************************************************/
void JSON_Parese1(int cid, cJSON *object){
    cJSON *func = cJSON_GetObjectItem(object, "功能");
    if(!strcmp(func->valuestring,"注册")){
        pthread_Register(cid, object);
    }else if(!strcmp(func->valuestring,"登录")){
        pthread_Login(cid, object);
    }else if(!strcmp(func->valuestring,"修改")){
        pthread_Update(cid, object);
    }else if(!strcmp(func->valuestring,"删除")){//删除文件
        pthread_Delete(cid, object);
    }else if(!strcmp(func->valuestring, "查询")){//即获取数据库中的相关文件名
        pthread_Find(cid, object);
    }
}

/*****************************************************************************
功  能:解析cJSON文件功能
参  数:
        acceptfd:用户套接字
        object:JSON
****************************************************************************/
void JSON_Parese2(int cid, cJSON *object){
    cJSON *func = cJSON_GetObjectItem(object, "功能");
    if(!strcmp(func->valuestring,"文件下载")){
        pthread_GetFile(cid,object);
    }else if(!strcmp(func->valuestring,"文件上传")){
        pthread_PutFile(cid, object);
    }else if(!strcmp(func->valuestring, "文件列表")){
        pthread_GetList(cid, object);
    }
}

/*****************************************************************************
功  能:注册用户,往数据库里存放
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_Register(int cid,cJSON *object){
    //解析cJSON

    //密码
    char *password = cJSON_GetObjectItem(object, "密码")->valuestring;
    //昵称
    char *name = cJSON_GetObjectItem(object,"昵称")->valuestring;
    //手机号
    char *num = cJSON_GetObjectItem(object, "手机号")->valuestring;

    //打开数据库
    sqlite3 *ppDb;
    sqlite3_open(DATABASE, &ppDb);
    //拼接sql语句
    char sql_insert[200] = {0};
    char *errmsg;
    sprintf(sql_insert, "insert into 用户信息表(密码, 昵称, 手机号) values('%s', '%s', '%s');", password, name, num);
    //执行数据sql语句
    if(sqlite3_exec(ppDb, sql_insert, NULL, NULL, &errmsg) != 0){
        //添加失败,给客户端返回消息
        //创建json对象
        cJSON *send_json = cJSON_CreateObject();
        //填入相应的错误信息
        cJSON_AddStringToObject(send_json, "功能", "注册");
        cJSON_AddStringToObject(send_json, "状态", "失败");
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        cJSON_AddStringToObject(send_json, "原因", errmsg);

        //发送个客户端
        char *send_str = cJSON_Print(send_json);
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);

        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }else{

        char sql_select[200] = {0};
        sprintf(sql_select, "select 账号 from 用户信息表 where 手机号 = '%s';", num);
        //执行sql语句
        char **pazResult;
        char *errmsg;
        int row, column;
        //获取账号
        sqlite3_get_table(ppDb, sql_select, &pazResult, &row, &column, &errmsg);
        //账号
        char *account = pazResult[1];

        //创建对应的文件夹
        char path[200] = {0};
        char path_str[250] = {0};
        getcwd(path,sizeof(path));
        sprintf(path_str, "%s/用户资源文件夹/%s", path, account);
        //转为整型
        int act = atoi(account);
        //printf("act = %d", act);
        //printf("%s\n",path_str);
        if(-1 == mkdir(path_str, 0777)){
            return -1;
        }
        
         //创建json对象
        cJSON *send_json = cJSON_CreateObject();
        //填入相应的错误信息
        cJSON_AddStringToObject(send_json, "功能", "注册");
        cJSON_AddStringToObject(send_json, "状态", "成功");
        cJSON_AddNumberToObject(send_json, "账号", act);
        cJSON_AddStringToObject(send_json, "密码", password);
        cJSON_AddStringToObject(send_json, "昵称", name);
        cJSON_AddStringToObject(send_json, "手机号", num);
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
        cJSON_AddStringToObject(send_json, "提醒", "请牢记你的账号密码");

        //发送给客户端
        char *send_str = cJSON_Print(send_json);
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);

        //关闭数据库
        sqlite3_close(ppDb);
        
    }
    
    return 0;
}

/*****************************************************************************
功  能:登录验证
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_Login(int cid,cJSON *object){
    //获取账号密码
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    char *password = cJSON_GetObjectItem(object, "密码")->valuestring;
    //打开数据库
    sqlite3 *ppDb;
    sqlite3_open(DATABASE, &ppDb);
    //拼接sql语句
    char sql_select[200] = {0};
    sprintf(sql_select, "select 账号, 密码 from 用户信息表 where 账号 = %d and 密码 = '%s';", account, password);

    //执行sql语句
    char **pazResult;
    char *errmsg;
    int row, column;
    if((sqlite3_get_table(ppDb, sql_select, &pazResult, &row, &column, &errmsg)) != 0){
        return -1;
    }
    if(row == 1){//查询成功
        //给客户端返回成功的信息
        cJSON *send_json = cJSON_CreateObject();
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
        char *send_str = cJSON_Print(send_json);
        write(cid, send_str, strlen(send_str));
        //销毁json对象
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
    }else{//查询失败,即没有该账号密码
        //给客户端返回成功的信息
        cJSON *send_json = cJSON_CreateObject();
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        char *send_str = cJSON_Print(send_json);
        write(cid, send_str, strlen(send_str));
        //销毁json对象
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }

    return 0;
}

/*****************************************************************************
功  能:根据账号修改密码
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_Update(int cid,cJSON *object){
    //获取其中的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    char *old_password = cJSON_GetObjectItem(object, "旧密码")->valuestring;
    char *new_password = cJSON_GetObjectItem(object, "新密码")->valuestring;

    //创建cJSON
    cJSON *send_json = cJSON_CreateObject();
    char *send_str = NULL;

    //对比旧密码
    if(-1 == use_password_compare(old_password, account)){
        //封装
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        cJSON_AddStringToObject(send_json, "原因", "旧密码错误\n");
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        return -1;
    }

    //打开数据库
    sqlite3 *ppDb;
    sqlite3_open(DATABASE, &ppDb);
    //拼接sql
    char sql_update[200] = {0};
    char *errmsg;
    sprintf(sql_update,"update 用户信息表 set 密码 = '%s' where 账号 = %d", new_password, account);
    //执行sql
    if(sqlite3_exec(ppDb, sql_update, NULL, NULL, &errmsg) != 0 ){//执行失败
        //封装
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        cJSON_AddStringToObject(send_json, "原因", errmsg);
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }else{

        //封装
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
    }

    return 0;
}

/*****************************************************************************
功  能:根据用户账号删除相关文件和数据库对应的数据
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_Delete(int cid,cJSON *object){
    //获取其中的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    //获取文件名
    char *filename = cJSON_GetObjectItem(object, "文件名")->valuestring;

    //创建cJSON
    cJSON *send_json = cJSON_CreateObject();
    char *send_str = NULL;
    //判断文件是否存在
    if(-1 == find_filename_exsit(filename, account)){
        //文件不存在
        //封装
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        cJSON_AddStringToObject(send_json, "原因", "文件不存在,无需删除\n");
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        return -1;
    }

    //文件存在,删除数据库中的数据和对应文件夹下的文件
    //打开数据库
    sqlite3 *ppDb;
    sqlite3_open(DATABASE, &ppDb);
    //拼接sql
    char sql_delete[200] = {0};
    char *errmsg;
    sprintf(sql_delete,"delete from 用户文件表 where 账号 = %d and 文件名 = '%s';", account, filename);
    //执行sql
    if(sqlite3_exec(ppDb, sql_delete, NULL, NULL, &errmsg) != 0 ){//执行失败
        //封装
        cJSON_AddNumberToObject(send_json, CODE, FAILED);
        cJSON_AddStringToObject(send_json, "原因", errmsg);
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }else{
        //删除对应的账号下的文件
        char path[100] = {0};
        getcwd(path,sizeof(path));
        char filepath_name[150] = {0};
        sprintf(filepath_name, "%s/用户资源文件夹/%d/%s", path, account,filename);
        remove(filepath_name);
        //封装
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
        //转换为字符串
        send_str = cJSON_Print(send_json);
        //发送
        write(cid, send_str, strlen(send_str));
        //销毁
        cJSON_Delete(send_json);
        //关闭数据库
        sqlite3_close(ppDb);
    }

    return 0;
}

/*****************************************************************************
功  能:查询数据库中用户对应的文件
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_Find(int cid,cJSON *object){
    //获取客户的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    //打开数据库
    sqlite3 *ppDb;
    sqlite3_open(DATABASE, &ppDb);
    //拼接sql
    char sql_select[200] = {0};
    sprintf(sql_select,"select a.文件名 from 用户信息表 s left join 用户文件表 a on s.账号 = a.账号 where s.账号 = %d", account);
     //执行sql语句
    char **pazResult;
    char *errmsg;
    int row = 0, column = 0;
    int i = 0, j = 0;
    //创建json
    cJSON *send_json = cJSON_CreateObject();
    cJSON *json_array = cJSON_CreateArray();
    cJSON *json_str = NULL;
    if((sqlite3_get_table(ppDb, sql_select, &pazResult, &row, &column, &errmsg)) != 0){
        return -1;
    }else if(row < 1){//查询成功,但是没有相关文件
        cJSON_AddStringToObject(send_json, "文件列表", NULL);
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
    }else{
        for(i = 1; i <= row; ++i){
            for(j = 0; j < column; ++j){
                json_str = cJSON_CreateString(pazResult[i*column + j]);
                cJSON_AddItemToArray(json_array, json_str);
            }
        }
        cJSON_AddItemToObject(send_json, "文件列表", json_array);
        cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
    }

    //发送
    char *send_str = cJSON_Print(send_json);
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);
    //关闭数据库
    sqlite3_close(ppDb); 
}

/*****************************************************************************
功  能:打开对应客户的目录,获取里面的文件列表
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_GetList(int cid,cJSON *object){
    //获取客户的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    
    //获取当前文件工作路径
    char path[200] = {0};
    getcwd(path,sizeof(path));
    char account_str[250] = {0};
    sprintf(account_str, "%s/用户资源文件夹/%d", path, account);
    //打开对应账户的目录
    DIR *dir;
    if(NULL == (dir = opendir(account_str))){
        return -1;
    }

    //走到这里,说明目录已存在,获取目录中的文件名
    //创建json数组
    cJSON *cjson_array = cJSON_CreateArray();
    cJSON *cjson_string = NULL;
    struct dirent *dirp;
    while(NULL != (dirp = readdir(dir))){
        if(strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0){
            continue;
        }
        cjson_string = cJSON_CreateString(dirp->d_name);
        cJSON_AddItemToArray(cjson_array,cjson_string);
    }
    //创建cjson
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddItemToObject(send_json, "文件列表", cjson_array);
    cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
    //转换为字符串
    char *send_str;
    send_str = cJSON_Print(send_json);
    //发送
    write(cid, send_str, strlen(send_str));

    //销毁
    cJSON_Delete(send_json);

    return 0;
}



/*****************************************************************************
功  能:文件上传
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_PutFile(int cid,cJSON *object){
    //获取客户的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    char *filename = cJSON_GetObjectItem(object, "文件名")->valuestring;
    
    //获取当前文件工作路径
    char path[100] = {0};
    getcwd(path,sizeof(path));
    char account_str[150] = {0};
    sprintf(account_str, "%s/用户资源文件夹/%d", path, account);

    //打开对应账户的目录
    DIR *dir;
    if(NULL == (dir = opendir(account_str))){
        return -1;
    }

    //走到这里,说明目录已存在,获取目录中的文件名
    cJSON *send_json = cJSON_CreateObject();
    char *send_str = NULL;
    struct dirent *dirp;
    while(NULL != (dirp = readdir(dir))){
        if(strcmp(dirp->d_name, filename) == 0 ){//文件存在,先返回相应的json,不需要上传了
            cJSON_AddNumberToObject(send_json, CODE, FAILED);
            cJSON_AddNumberToObject(send_json, "状态", FAILED);
            //转换为字符串
            send_str = cJSON_Print(send_json);
            //发送
            write(cid, send_str, strlen(send_str));
            //销毁
            cJSON_Delete(send_json);
            return -1;
        }
    }
    //这里说明没有重复文件
    cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
    //已做好接收准备信号
    cJSON_AddNumberToObject(send_json, "状态", SUCCESS);
    //转换为字符串
    send_str = cJSON_Print(send_json);

    //发送
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);

    struct common msg = {0};
    int ret = 0;
    int fd = 0;
    strcat(account_str,"/");
    strcat(account_str, filename);
    if(-1 == (fd = open(account_str, O_WRONLY|O_CREAT, 0666))){
        return -1;
    }
    //打开相应文件
    while(1){
        ret = read(cid, &msg, sizeof(msg));
        if(ret <= 0 || msg.num == 0){
            break;
        }
        write(fd, msg.data, msg.num);
    }

    //接收完毕后需要将文件名保存到对应的数据库中
    if(insert_filename(filename, account) == -1){//表述插入数据库失败
        return -1;
    }
    return 0;
}

/*****************************************************************************
功  能:文件下载
参  数:
        cid:客户端套接字
        object:cJSON对象
返回值:0表示成功,-1表示失败
****************************************************************************/
int pthread_GetFile(int cid,cJSON *object){
    //获取客户的账号
    int account = cJSON_GetObjectItem(object, "账号")->valueint;
    char *filename = cJSON_GetObjectItem(object, "文件名")->valuestring;
    //获取当前文件工作路径
    char path[100] = {0};
    getcwd(path,sizeof(path));
    char account_str[150] = {0};
    sprintf(account_str, "%s/用户资源文件夹/%d", path, account);

    //打开对应账户的目录
    DIR *dir;
    if(NULL == (dir = opendir(account_str))){
        return -1;
    }

    //走到这里,说明目录已存在,获取目录中的文件名
    cJSON *send_json = cJSON_CreateObject();
    char *send_str = NULL;
    struct dirent *dirp;
    while(NULL != (dirp = readdir(dir))){
        if(strcmp(dirp->d_name, filename) == 0 ){//文件存在,先返回相应的json
            cJSON_AddNumberToObject(send_json, CODE, SUCCESS);
            //转换为字符串
            send_str = cJSON_Print(send_json);
            //发送
            write(cid, send_str, strlen(send_str));
            //销毁
            cJSON_Delete(send_json);
            //接收客户端已经做好就收的准备
            char buf[1024];
            if(read(cid, buf, sizeof(buf)) <= 0){
                return -1;
            }

            //解析json
            cJSON *recv_json = cJSON_Parse(buf);
            if(recv_json == NULL){
               return -1;
            }
            
            cJSON *temp  = cJSON_GetObjectItem(recv_json, "状态");
            if(temp->valueint == SUCCESS){
                //发送文件
                int fd = 0;
                strcat(account_str, "/");
                strcat(account_str,filename);
                if(-1 == (fd = open(account_str, O_RDONLY))){
                    return -1;
                }
                
                struct common msg = {0};
                int ret;
                while(1){
                    ret = read(fd, msg.data, sizeof(msg.data));
                    msg.num = ret;
                    write(cid, &msg, sizeof(msg));
                    if(ret <= 0){
                        break;
                    }
                }
                cJSON_Delete(recv_json);
                close(fd);
                return 0;
            }
            
        }
    }
    //执行到此说明没有该文件
    cJSON_AddNumberToObject(send_json, CODE, FAILED);
    //转换为字符串
    send_str = cJSON_Print(send_json);
    //发送
    write(cid, send_str, strlen(send_str));

    //销毁
    cJSON_Delete(send_json);

    return -1;

}

/*****************************************************************************
功  能:保存用户相关文件到数据库
参  数:
    filename:文件名
    act:账号
返回值:0表示成功,-1表示失败
****************************************************************************/
static int insert_filename(char *filename, int act){
    //打开数据库
    sqlite3 *ppDb = NULL;
    sqlite3_open(DATABASE, &ppDb);
    
    //拼装sql语句
    char sql_insert[100] = {0};
    sprintf(sql_insert, "insert into 用户文件表(账号, 文件名) values(%d, '%s');", act, filename);

    //执行sql语句
    if(sqlite3_exec(ppDb, sql_insert, NULL, NULL, NULL) != 0){
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }

    //关闭数据库
    sqlite3_close(ppDb);
    return 0;
}

/*****************************************************************************
功  能:查询某账户中某文件是否存在
参  数:
    filename:文件名
    act:账号
返回值:0表示存在,-1表示不存在
****************************************************************************/
static int find_filename_exsit(char *filename, int act){
    //打开数据库
    sqlite3 *ppDb = NULL;
    sqlite3_open(DATABASE, &ppDb);
    
    //拼装sql语句
    char sql_insert[100] = {0};
    sprintf(sql_insert, "select 文件名 from 用户文件表 where 账号 = %d and 文件名 = '%s';", act, filename);
    //执行sql语句
    char **pazResult = NULL;
    char *errmsg = NULL;
    int row = 0, column = 0;
    if(sqlite3_get_table(ppDb, sql_insert, &pazResult, &row, &column, &errmsg) != 0){
        return -1;
    }

    //查询出来row是真实的数据的行数

/*     printf("row = %d\n",row);
    for(int i = 0; i <= row; i++){
        for(int j = 0; j < column; j++){
            printf("%s\n", pazResult[i*column + j]);
        }
    } */
    if(row < 1){
        //说明没有数据,及文件不存在
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }

    //关闭数据库
    sqlite3_close(ppDb);
    return 0;
}


/*****************************************************************************
功  能:修改密码的时候将旧密码和数据库密码进行比对
参  数:
    old_password:旧密码
    act:账号
返回值:0表示相同,-1表示不相同
****************************************************************************/
static int use_password_compare(char *old_password, int act){
        //打开数据库
    sqlite3 *ppDb = NULL;
    sqlite3_open(DATABASE, &ppDb);
    
    //拼装sql语句
    char sql_insert[100] = {0};
    sprintf(sql_insert, "select 密码 from 用户信息表 where 账号 = %d;", act);
    //执行sql语句
    char **pazResult = NULL;
    char *errmsg = NULL;
    int row = 0, column = 0;
    if(sqlite3_get_table(ppDb, sql_insert, &pazResult, &row, &column, &errmsg) != 0){
        return -1;
    }

    if(row < 1){//没查到
        //说明没有数据,及文件不存在
        //关闭数据库
        sqlite3_close(ppDb);
        return -1;
    }

    if(!strcmp(pazResult[1], old_password)){
        //相同
        //关闭数据库
        sqlite3_close(ppDb);
        return 0;
    }

    //不相同
    //关闭数据库
    sqlite3_close(ppDb);
    return -1;
}

客户端中的main.c ,客户端中没有使用多线程和多进程,所以无法实现都文件下载

/*************************************************************************
> File Name:client
> Author: Lxx
> Created Time: 2023-03-01 13:54:21
> description: 网盘系统基于TCP的客户端
> version: 1.0
************************************************************************/

#include "client.h"

int main(int argc, const char *argv[])
{
    //创建流式套接字
    int sockfd1 = 0, sockfd2 = 0;
    if(-1 == (sockfd1 = socket(AF_INET, SOCK_STREAM, 0))){
        ERRLOG("sockfd error");
    }
    if(-1 == (sockfd2 = socket(AF_INET, SOCK_STREAM, 0))){
        ERRLOG("sockfd error");
    }

    //填充网络信息结构体
    struct sockaddr_in serveraddr = {0};
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(PORT1);
    serveraddr.sin_addr.s_addr = inet_addr(IP);
    socklen_t sockaddr_len = sizeof(serveraddr);

    //连接服务器
    if(-1 == (connect(sockfd1, (struct sockaddr *)&serveraddr, sockaddr_len))){
        //连接失败
        ERRLOG("accept error");
    }

    serveraddr.sin_port = htons(PORT2);
    if(-1 == (connect(sockfd2, (struct sockaddr *)&serveraddr, sockaddr_len))){
        //连接失败
        ERRLOG("accept error");
    }
    welcome_UI(sockfd1,sockfd2);

        

    //关闭套接字
    close(sockfd1);
    close(sockfd2);
    return 0;
}

client.c

#include "client.h"

/*****************************************************************************
功  能:欢迎界面
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
****************************************************************************/
void welcome_UI(int cid, int cid2){
    system("clear");
    printf("\t\t--------------------------------------------------\n");
    printf("\t\t                                                 \n");
    printf("\t\t                                                 \n");
    printf("\t\t                欢迎使用网盘系统                  \n");
    printf("\t\t                                                 \n");
    printf("\t\t                                                 \n");
    printf("\t\t                                                 \n");
    printf("\t\t--------------------按回车键继续--------------------\n");
    printf("\t\t");
    getchar();
    system("clear");
    use_UI(cid, cid2);
}

/*****************************************************************************
功  能:用户界面
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
****************************************************************************/
void use_UI(int cid, int cid2){
    char c;
    printf("\t\t--------------------------------------------------\n");
    printf("\t\t                  用户登录页面                     \n");
    printf("\t\t                                                 \n");
    printf("\t\t                  1.登陆用户                      \n");
    printf("\t\t                  2.注册用户                      \n");
    printf("\t\t                                                 \n");
    printf("\t\t                                                 \n");
    printf("\t\t-------------------请输入对应数字-------------------\n");
    printf("\t\t");
    scanf("%c", &c);
    //清空缓存区,把换行符(\n)拿走
    getchar();
    if(c == '1'){
        //清空当前终端页面
        system("clear");
        login_UI(cid, cid2);
    }else if(c == '2'){
        system("clear");
        register_UI(cid, cid2);
    }else{
        system("clear");
        login_UI(cid, cid2);
    }
}

/*****************************************************************************
功  能:登录用户页面
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
****************************************************************************/
void login_UI(int cid, int cid2){

    char c;
    char name[20] = {0}, password[20] = {0};
    printf("\t\t--------------------------------------------------\n");
    printf("\t\t                  请你登录                         \n");
    printf("\t\t                                                  \n");

    printf("\t\t                  账 号:                         \n");
    printf("\t\t");
    fgets(name,sizeof(name), stdin);
    name[strlen(name)-1] = '\0';
    printf("\t\t                  密  码:                         \n");
    printf("\t\t");
    fgets(password,sizeof(password), stdin);
    password[strlen(password)-1] = '\0';
    printf("\t\t                                                  \n");
    printf("\t\t                                                  \n");
    printf("\t\t-------------------请按回车登录----------------------\n");
    printf("\t\t");
    getchar();
    
    //将数据封装为json
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "登录");
    //将账号转为整型
    cJSON_AddNumberToObject(send_json, "账号", atoi(name));
    cJSON_AddStringToObject(send_json, "密码", password);
    //转换为字符串
    char *send_str = cJSON_Print(send_json);

    //发送
    write(cid, send_str, strlen(send_str));
    //释放
    cJSON_Delete(send_json);

    //接收服务器返回的json数据
    char buf[1024] = {0};
    if(read(cid, buf, 1024) <= 0){
        return;
    } 
    //printf("%s\n", buf);
    cJSON *object = cJSON_Parse(buf);
    if(object == NULL){
        return;
    }

    //解析
    cJSON *func = cJSON_GetObjectItem(object, "标记");
    if(func == NULL){
        return;
    }
    if(func->valueint == SUCCESS){
        //表示登录成功,跳转到功能页面
        int act = atoi(name);//保留账号
        cJSON_Delete(object);
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        printf("\t\t登录失败,账号或密码错误,请按回车重新登录或者输入1回车,去注册\n");
        char a;
        scanf("%c", &a);
        getchar();
        if(a == '1'){
            system("clear");
            register_UI(cid, cid2);
        }else{
            system("clear");
            login_UI(cid, cid2);
        }
    }
}

/*****************************************************************************
功  能:注册用户页面
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
****************************************************************************/
void register_UI(int cid, int cid2){

    char password[20] = {0}, name[20] = {0}, num[20] = {0};
    printf("\t\t--------------------------------------------------\n");
    printf("\t\t                 请你注册                         \n");
    printf("\t\t                                                 \n");

    printf("\t\t                 昵 称:                          \n");
    printf("\t\t");
    fgets(name,sizeof(name), stdin);
    name[strlen(name)-1] = '\0';

    printf("\t\t                 密 码:                           \n");
    printf("\t\t");
    fgets(password,sizeof(password), stdin);
    password[strlen(password)-1] = '\0';
    printf("\t\t                 手机号:                           \n");
    printf("\t\t");
    fgets(num,sizeof(num), stdin);
    num[strlen(num)-1] = '\0';
    printf("\t\t                                                 \n");
    printf("\t\t                                                 \n");
    printf("\t\t------------------按回车注册------------------------\n");

    //创建json
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "注册");
    cJSON_AddStringToObject(send_json, "昵称", name);
    cJSON_AddStringToObject(send_json, "密码", password);
    cJSON_AddStringToObject(send_json, "手机号", num);

    //转化为字符串
    char *send_str = cJSON_Print(send_json);
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);

    //接收返回的json
    char buf[1024] = {0};
    if(read(cid, buf, 1024) <= 0){
        return;
    }

    //将字符串转换为json
    cJSON *recv_json = cJSON_Parse(buf);
    if(recv_json == NULL){
        return;
    }

    cJSON *str = cJSON_GetObjectItem(recv_json, "标记");
    if(str == NULL){
        return;
    }
    if(str->valueint == SUCCESS){
        //注册成功
        //打印注册账号
        cJSON *account = cJSON_GetObjectItem(recv_json, "账号");
        int act = account->valueint;
        
        printf("\t\t恭喜你注册成功,你的账号为  %d  ,请牢记\n", act);
        printf("\t\t请按回车给自动登录...\n");
        //销毁json
        cJSON_Delete(recv_json);

        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        //注册失败
        //销毁json
        cJSON *msg = cJSON_GetObjectItem(recv_json, "原因");
        printf("错误原因:%s\n",msg->valuestring);
        cJSON_Delete(recv_json);
        printf("请按回车,重新注册\n");
        getchar();
        register_UI(cid, cid2);
    }

}

/*****************************************************************************
功  能:功能页面
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void function_UI(int cid, int cid2, int act){
    char c;
    printf("\t\t--------------------------------------------------\n");
    printf("\t\t                  用户功能页面                     \n");
    printf("\t\t                                                 \n");
    printf("\t\t                  1.文件列表                      \n");
    printf("\t\t                  2.文件下载                      \n");
    printf("\t\t                  3.文件上传                      \n");
    printf("\t\t                  4.文件删除                      \n");
    printf("\t\t                  5.修改密码                      \n");
    printf("\t\t                  6.切换用户                      \n");
    printf("\t\t                  7.退出系统                      \n");
    printf("\t\t                                                 \n");
    printf("\t\t-------------------请输入对应数字-------------------\n");
    printf("\t\t");
    scanf("%c", &c);
    //清空缓存区,把换行符(\n)拿走
    getchar();
    if(c == '1'){
        //清空当前终端页面
        system("clear");
        file_list_UI(cid, cid2, act);
    }else if(c == '2'){
        system("clear");
        file_download_UI(cid, cid2, act);
    }else if(c == '3'){
        system("clear");
        file_Upload_UI(cid, cid2, act);
    }else if(c == '4'){
        system("clear");
        file_delete_UI(cid, cid2, act);
    }else if(c == '5'){
        system("clear");
        use_update_UI(cid, cid2, act);
    }else if(c == '6'){
        system("clear");
        login_UI(cid, cid2);
    }else if(c == '7'){
        //system("clear");
        close(cid);
        close(cid2);
        exit(0);
    }else{
        system("clear");
        function_UI(cid, cid2, act);
    }
}

/*****************************************************************************
功  能:显示当前用户的所有文件
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void file_list_UI(int cid, int cid2, int act){
    
    //向服务器发请求,得到所有文件列表
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能","查询");
    cJSON_AddNumberToObject(send_json, "账号", act);
    char *send_str = cJSON_Print(send_json);
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);

    //接收服务器返回的json
    char buf[1024] = {0};
    if(read(cid, buf, 1024) <= 0){
        return;
    }

    //转换为cjson
    cJSON *recv_json = cJSON_Parse(buf);
    cJSON *msg = cJSON_GetObjectItem(recv_json,"文件列表");
    cJSON *str = NULL;
    int i = 0;
    printf("\t\t--------------------------------------------------\n");
    if(msg != NULL){
        int array_size = cJSON_GetArraySize(msg);
        for(i = 0; i < array_size; ++i){
            str = cJSON_GetArrayItem(msg, i);
            if(str != NULL){
                printf("\t\t%s\n",str->valuestring);
            }
        }
    }
    printf("\t\t--------------------------------------------------\n");
    
    //销毁json
    cJSON_Delete(recv_json);

    printf("\t\t已显示完毕,按下回车回到功能页面\n");
    printf("\t\t");
    getchar();
    system("clear");
    function_UI(cid, cid2, act);
}


/*****************************************************************************
功  能:文件下载
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void file_download_UI(int cid, int cid2, int act){
    //发送文件下载json
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "文件下载");
    cJSON_AddNumberToObject(send_json, "账号", act);
    //文件名
    char filename[20] = {0};
    printf("\t\t你要下载的文件名:\n");
    printf("\t\t");
    fgets(filename,sizeof(filename), stdin);
    filename[strlen(filename)-1] = '\0';
    cJSON_AddStringToObject(send_json, "文件名", filename);

    char *send_str = cJSON_Print(send_json);
    write(cid2, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);
    
    //接收服务器返回的json
    char buf[1024] = {0};
    if(read(cid2, buf, 1024) <= 0){
        return;
    }
    cJSON *recv_json = cJSON_Parse(buf);
    cJSON *str = cJSON_GetObjectItem(recv_json, CODE);
    struct common msg = {0};
    if(str->valueint == SUCCESS){

        //发送一个可以接收的json给服务器
        cJSON *send_json = cJSON_CreateObject();
        cJSON_AddNumberToObject(send_json, "状态", SUCCESS);
        char *send_str = cJSON_Print(send_json);
        write(cid2, send_str, strlen(send_str));
        cJSON_Delete(send_json);
        
        //接收文件
        int fd;
        if(-1 == (fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666))){
            return;
        }
        int ret = 0;
        while(1){
            //文件存在,接收服务器发送文件
            ret = read(cid2, &msg, sizeof(msg));
            if(ret <= 0 || msg.num == 0){
                break;
            }
            //写服务器发来的文件
            write(fd, msg.data, msg.num);
        }
        //关闭文件描述符
        close(fd);
        //销毁json
        cJSON_Delete(recv_json);
        printf("\t\t下载成功\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        //文件不存在
        printf("\t\t文件不存在\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }
    
}

/*****************************************************************************
功  能:文件上传
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void file_Upload_UI(int cid, int cid2, int act){
    //发送文件上传json信号
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "文件上传");
    cJSON_AddNumberToObject(send_json, "账号", act);
    //文件路径
    char filename_path[100];
A:
    memset(filename_path, 0, sizeof(filename_path));
    printf("\t\t你要上传的文件路径:\n");
    printf("\t\t");
    fgets(filename_path,sizeof(filename_path), stdin);
    filename_path[strlen(filename_path)-1] = '\0';

    //先判断文件是否存在,如果存在直接返回,不发数据给服务器
    struct common msg = {0};
    int fd;
    if(-1 == (fd = open(filename_path, O_RDONLY))){
        printf("\t\t文件不存在,请重新填写文件名\n");
        goto A;
    }

    //剪切文件名
    char *filename = strrchr(filename_path, '/');
    if(filename != NULL){//找到了
        //往前移一位
        filename += 1;
    }else{
        filename = filename_path;
    }

    cJSON_AddStringToObject(send_json, "文件名", filename);
    char *send_str = cJSON_Print(send_json);
    write(cid2, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);
    
    //接收服务器返回的json
    char buf[1024] = {0};
    if(read(cid2, buf, 1024) <= 0){
        return;
    }

    cJSON *recv_json = cJSON_Parse(buf);
    cJSON *str = cJSON_GetObjectItem(recv_json, CODE);
    if(str == NULL){
        return;
    }
    if(str->valueint == SUCCESS){

        cJSON *temp = cJSON_GetObjectItem(recv_json, "状态");
        //接收服务器是否准备好接收
        if(temp != NULL){
            if(temp->valueint == SUCCESS){//表示已做好接收准备
                    //释放上一个json的空间
                cJSON_Delete(recv_json);
                //发送文件
                int ret = 0;
                while(1){
                    //文件存在,接收服务器发送文件
                    ret = read(fd, msg.data, sizeof(msg.data));
                    msg.num = ret;
                    //向服务器发文件
                    write(cid2, &msg, sizeof(msg));
                    if(ret <= 0){
                        break;
                    }
                }
            }
        }
        //关闭文件描述符
        close(fd);
        printf("\t\t上传成功\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        //文件存在
        close(fd);
        printf("\t\t文件存在,无需上传\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }
}

/*****************************************************************************
功  能:文件删除
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void file_delete_UI(int cid, int cid2, int act){
     //发送文件上传json信号
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "删除");
    cJSON_AddNumberToObject(send_json, "账号", act);

    //文件名
    char filename[20];
    memset(filename, 0, sizeof(filename));
    printf("\t\t你要删除的文件:\n");
    printf("\t\t");
    fgets(filename,sizeof(filename), stdin);
    filename[strlen(filename)-1] = '\0';

    cJSON_AddStringToObject(send_json, "文件名", filename);
    char *send_str = cJSON_Print(send_json);
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);

    //接收服务器传来的json
    char buf[1024];
    if(-1 == read(cid, buf, sizeof(buf))){
        return;
    }

    cJSON *recv_json = cJSON_Parse(buf);
    cJSON *code = cJSON_GetObjectItem(recv_json, CODE);
    if(code->valueint == SUCCESS){
        cJSON_Delete(recv_json);
        //删除成功
        printf("\t\t删除成功\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        //删除失败
        cJSON *because = cJSON_GetObjectItem(recv_json, "原因");
        printf("\t\t删除失败\n");
        printf("\t\t原因:%s\n",because->valuestring);
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        cJSON_Delete(recv_json);
        getchar();
        system("clear");
        function_UI(cid, cid2, act);

    }

}


/*****************************************************************************
功  能:用户修改密码
参  数:
    cid:对应服务器port1
    cid2:对应服务器poet2
    act:为用户账号
****************************************************************************/
void use_update_UI(int cid, int cid2, int act){
     //发送文件上传json信号
    cJSON *send_json = cJSON_CreateObject();
    cJSON_AddStringToObject(send_json, "功能", "修改");
    cJSON_AddNumberToObject(send_json, "账号", act);
    //输入新旧密码
    char old_password[20] = {0}, new_password[20] = {0};
    printf("\t\t输入你的旧密码:\n");
    printf("\t\t");
    fgets(old_password,sizeof(old_password), stdin);
    old_password[strlen(old_password)-1] = '\0';

    printf("\t\t输入你的新密码:\n");
    printf("\t\t");
    fgets(new_password,sizeof(new_password), stdin);
    new_password[strlen(new_password)-1] = '\0';

    cJSON_AddStringToObject(send_json, "旧密码", old_password);
    cJSON_AddStringToObject(send_json, "新密码", new_password);

    char *send_str = cJSON_Print(send_json);
    write(cid, send_str, strlen(send_str));
    //销毁
    cJSON_Delete(send_json);

    //接收服务器传来的json
    char buf[1024];
    if(-1 == read(cid, buf, sizeof(buf))){
        return;
    }

    cJSON *recv_json = cJSON_Parse(buf);
    cJSON *code = cJSON_GetObjectItem(recv_json, CODE);
    if(code->valueint == SUCCESS){
        cJSON_Delete(recv_json);
        //修改成功
        printf("\t\t修改成功\n");
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        getchar();
        system("clear");
        function_UI(cid, cid2, act);
    }else{
        //修改失败
        cJSON *because = cJSON_GetObjectItem(recv_json, "原因");
        printf("\t\t修改失败\n");
        printf("\t\t原因:%s\n",because->valuestring);
        printf("\t\t按回车回到功能页面\n");
        printf("\t\t");
        cJSON_Delete(recv_json);
        getchar();
        system("clear");
        function_UI(cid, cid2, act);

    }

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值