嵌入式养成计划-48----QT--信息管理系统:百川仓储管理

news2024/10/5 13:35:15

一百二十二、信息管理系统:百川仓储管理

122.1 UI界面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

122.2 思路

  • 客户端: 用户权限有两种类型,一种是用户权限,一种是管理员权限,登录时服务器端会根据数据库查询到的此用户名的权限返回不同的结果,客户端会根据这个结果打开不同的操作界面。
    用户 可以进行登录、注册,存取物品,查询个人信息,修改密码,查看仓库库存,查看个人操作记录;
    管理员 可以进行登录,存取物品,查看仓库库存,查看所有用户,修改用户密码,提升用户权限为管理员,删除用户,添加用户,查看所有操作记录;
  • 服务器端: 服务器端根据不同的数据包进行不同的操作,然后发回不同的数据包。在服务器端使用set容器防止使用者重复登录— —每次登录成功时都会往容器中加入这个用户名,每次登录时都会检查这个容器中是否有这个名字,如果有,那就登录失败;断开链接时会删除这个用户名。每次登录时都会记录用户名,方便后面进行存放历史记录。
  • 数据库: 数据库用的是 sqlite3 ,数据库中有三个表,用户表(user)、物品信息表(item_info)、历史记录表(history)。
  • 传输层协议: TCP。

这个项目可以部署在云服务器上:
服务器代码在云服务器运行,服务器端IP绑定为云服务器的内网IP;
客户端连接的服务器IP绑定为云服务器的公网IP。
客户端可以通过工具打包成一个exe文件,步骤可以去B站搜搜

122.3 代码

  • 客户端代码文件太多了,就不直接放代码了,直接上传项目包
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 服务器端代码有点长

122.4 服务器端代码

main.cpp

#include "server.h"

sqlite3 *sqldb = nullptr;

int main(int argc, const char *argv[])
{

    if (sqlite3_open("../warehouse.db", &sqldb) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_open error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return -1;
    }
    printf("数据库打开成功\n");

    // 创建用户表
    char sql_str[128] = "";
    strcpy(sql_str, "CREATE TABLE if not exists user(uname char,passwd char,privilege char,signin_time char)");
    char *error_msg = NULL;
    if (sqlite3_exec(sqldb, sql_str, NULL, NULL, &error_msg) != SQLITE_OK)
    {
        fprintf(stderr, "create table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), error_msg, __LINE__);
        return -1;
    }
    printf("用户表创建成功\n");

    // 创建历史记录表
    strcpy(sql_str, "CREATE TABLE if not exists history\
        (uname char,operation char,Obj char,optime char,oper_ip char)");
    char *error_msg2 = NULL;
    if (sqlite3_exec(sqldb, sql_str, NULL, NULL, &error_msg2) != SQLITE_OK)
    {
        fprintf(stderr, "create table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), error_msg2, __LINE__);
        return -1;
    }
    printf("历史记录表创建成功\n");

    // 创建物品信息表
    strcpy(sql_str, "CREATE TABLE if not exists item_info\
        (item_name char,supplier char,numb int,input_name char,input_time char)");
    char *error_msg3 = NULL;
    if (sqlite3_exec(sqldb, sql_str, NULL, NULL, &error_msg3) != SQLITE_OK)
    {
        fprintf(stderr, "create table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), error_msg3, __LINE__);
        return -1;
    }
    printf("物品信息表创建成功\n");

    //  创建流式套接字  服务器
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("套接字创建成功 server_fd = %d\n", server_fd);

    //  允许端口快速复用
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速复用成功\n");

    //  绑定服务器的地址信息    必须绑定
    struct sockaddr_in server_in;                     //  用于绑定本主机的信息
    server_in.sin_family = AF_INET;                   //  必须填 AF_UNIX
                                                      //  因为前面创建流式套接字用的是 IPv4
    server_in.sin_port = htons(SERVER_PORT);          //  指定端口号
    server_in.sin_addr.s_addr = inet_addr(SERVER_IP); //  绑定本机IP
    if (bind(server_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0)
    {
        ERR_MSG("bin");
        return -1;
    }
    printf("bind 成功\n");

    //  将套接字转换为被动监听状态
    if (listen(server_fd, 256) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen 成功\n");

    //  获取连接成功的客户端信息,生成一个新的文件描述符
    //  该文件描述符才是与客户端通信的文件描述符
    client_info info; //  用于存放接收的客户端的信息
    // struct sockaddr_in client_in;          //  用于存放接收的客户端的信息
    socklen_t addrlen = sizeof(info.c_in); //  用于存放客户端传来的信息的长度

    int new_fd;

    while (1)
    {
        new_fd = accept(server_fd, (struct sockaddr *)&info.c_in, &addrlen); //  连接客户端
        if (new_fd < 0)
        {
            ERR_MSG("accept");
            return -1;
        }
        info.new_fd = new_fd;
        //  输出客户端IP和端口号
        printf("[%s : %d]已连接 new_fd = %d \n", inet_ntoa(info.c_in.sin_addr), ntohs(info.c_in.sin_port), new_fd);

        //  创建线程处理客户端发来的连接和数据
        pthread_t tid1;
        if (pthread_create(&tid1, NULL, thread, (void *)&info) != 0)
        {
            fprintf(stderr, "线程创建错误 __%d__\n", __LINE__);
        }
        pthread_detach(tid1);
    }

    //  关闭套接字
    close(server_fd);
    close(new_fd);
    return 0;
}

server.h

#ifndef __SERVER_H__
#define __SERVER_H__

#include <my_head.h>
#include <iostream>
#include <string>
#include <set>

#define DATA_SIZE 1500

#define SERVER_IP "内网IP"
// #define SERVER_IP "127.0.0.1" //  服务器IP
#define SERVER_PORT 6666

#define ROOT "zhk"

typedef struct thread_arg
{
    int new_fd;
    struct sockaddr_in c_in;
} client_info;

//  外部变量,打开服务器
extern sqlite3 *sqldb;

enum
{
    LOGIN = 1,        //  登录
    SIGNIN,           //  注册
    CHANGE_PASSWD,    //  修改密码
    SAVE,             //  存物品
    GET_OUT,          //  取物品
    CHECK_ITEMS,      //  查看物品
    CHECK_HISTORY,    //  查看历史记录
    CHANGE_PRIVILEGE, //  修改权限
    CHECK_INFO,       //  查看个人信息
    DELETE_USER,      //  删除用户
    FIND_ALL_USER,    //  查看所有用户

    LOGIN_OR_SIGNIN_SUCCESS = 11, //  普通用户 登录/注册 成功
    ADMIN_LOGIN_SUCESS,           //  管理员登录成功
    LOGIN_OR_SIGNIN_FAILURE,      //  登录/注册 失败
    CHANGE_PASSWD_SUCCESS,        //  密码修改成功
    CHANGE_PASSWD_FAILURE,        //  密码修改失败
    CHANGE_PRIVILEGE_SUCESS,      //  权限修改成功
    CHANGE_PRIVILEGE_FAILURE,     //  权限修改失败
    DELETE_USER_SUCESS,           //  删除用户成功
    DELETE_USER_FAILURE,          //  删除用户失败

    SAVE_SUCESS = 21, //  存放成功
    SAVE_FAILURE,     //  存放失败
    GET_OUT_SUCESS,   //  取出成功
    GET_OUT_FAILURE,  //  取出失败
    CHECK_SUCESS,     //  查看成功
    CHECK_FAILURE,    //  查看失败

};

//  线程处理 与客户端连接
void *thread(void *arg);

//  处理 查看物品 功能
void deal_CHECK_ITEMS(char *buff, client_info &cli, char *name);

//  处理 查看历史记录 功能
void deal_CHECK_HISTORY(char *buff, client_info &cli, char *name);

//  处理 查询所有用户 功能
void deal_FIND_ALL_USER(char *buff, client_info &cli, char *name);

//  处理 修改权限 功能
void deal_CHANGE_PRIVILEGE(char *buff, client_info &cli, char *name);

//  处理 删除用户 功能
void deal_DELETE_USER(char *buff, client_info &cli, char *name);

//  处理 修改密码 功能
void deal_CHANGE_PASSWD(char *buff, client_info &cli, char *name);

//  处理 查看 个人信息 功能
void deal_CHECK_INFO(char *buff, client_info &cli, char *name);

//  处理 取出物品 功能
void deal_GET_OUT(char *buff, client_info &cli, char *name);

//  处理 存放物品 功能
void deal_SAVE(char *buff, client_info &cli, char *uname);

//  处理登录功能
void deal_LOGIN(char *buff, client_info &cli, char *uname);

//  处理注册功能
void deal_SIGNIN(char *buff, client_info &cli);

// 查询历史记录
int deal_find_history(int new_fd, char *buff, struct sockaddr_in client_in, sqlite3 *sqldb);
// 与服务器通信

// 获取当前时间,返回字符串
char *get_time(char *now_time);
// 获取服务器信息,返回字符串
char *get_client_info(struct sockaddr_in client_in, char *info);

// 数据库操作
// 查询数据
int select_data_ret_num(char *sql_str, sqlite3 *sqldb);
// 插入数据
int insert_data(char *sql_str, sqlite3 *sqldb);

#endif

server.cpp

#include "server.h"
using namespace std;

set<string> signin_set;

void *thread(void *arg)
{
    client_info th_arg = *((client_info *)arg);

    //  存放 接收的数据
    char buff[128];
    //  操作码
    char *opcode = buff;

    char uname[128];
    ssize_t res = 0;

    while (1)
    {
        //  清空暂存区
        bzero(buff, sizeof(buff));
        //  接收数据
        res = read(th_arg.new_fd, buff, sizeof(buff));

        if (res < 0)
        {
            ERR_MSG("recv");
            break;
        }
        //  写端关闭了,即客户端关闭
        else if (0 == res)
        {
            printf("[ %s : %d ]客户端断开链接\n", inet_ntoa(th_arg.c_in.sin_addr),
                   ntohs(th_arg.c_in.sin_port));
            goto THREAD_END;
        }

        // 对接收的消息进行分类处理
        switch (*opcode)
        {
        case LOGIN: //  登录请求
            deal_LOGIN(buff, th_arg, uname);
            break;
        case SIGNIN: //  注册请求
            deal_SIGNIN(buff, th_arg);
            break;
        case CHANGE_PASSWD: //  修改密码
            deal_CHANGE_PASSWD(buff, th_arg, uname);
            break;
        case SAVE: //  存物品
            deal_SAVE(buff, th_arg, uname);
            break;
        case GET_OUT: //  取物品
            deal_GET_OUT(buff, th_arg, uname);
            break;
        case CHECK_ITEMS: //  查看物品
            deal_CHECK_ITEMS(buff, th_arg, uname);
            break;
        case CHECK_HISTORY: //  查看历史记录
            deal_CHECK_HISTORY(buff, th_arg, uname);
            break;
        case CHANGE_PRIVILEGE: //  修改权限
            deal_CHANGE_PRIVILEGE(buff, th_arg, uname);
            break;
        case CHECK_INFO: //  查询个人信息
            deal_CHECK_INFO(buff, th_arg, uname);
            break;
        case DELETE_USER: //  删除用户
            deal_DELETE_USER(buff, th_arg, uname);
            break;
        case FIND_ALL_USER: //  查看所有用户
            deal_FIND_ALL_USER(buff, th_arg, uname);
            break;
        default:
            break;
        }

    }

THREAD_END:
    if (!signin_set.empty() && signin_set.find(uname) != signin_set.end())
    {
        signin_set.erase(uname);
    }
    close(th_arg.new_fd);
    pthread_exit(NULL);
}

//  处理 查看物品 功能
void deal_CHECK_ITEMS(char *buff, client_info &cli, char *name)
{
    //  获取客户传来的内容
    char *item = buff + 1;
    char *supplier = item + 1 + strlen(item);
    char sql_str[256];
    char ret_msg[512] = "CHECK_FAILURE";
    sprintf(sql_str, "select * from item_info ");
    //  如果 或物品, 或供应商,有任何一个存在,则加上where
    if (strcmp(item, "") || strcmp(supplier, ""))
    {
        strcat(sql_str, "where ");
    }

    //  SQL语句追加
    if (strcmp(item, ""))
    {
        char item_cat[32] = "";
        sprintf(item_cat, "item_name='%s' ", item);
        strcat(sql_str, item_cat);

        if (strcmp(supplier, ""))
        {
            char supplier_cat[32] = "";
            sprintf(supplier_cat, "and supplier='%s' ", supplier);
            strcat(sql_str, supplier_cat);
        }
    }
    else
    {
        if (strcmp(supplier, ""))
        {
            char supplier_cat[32] = "";
            sprintf(supplier_cat, "supplier='%s' ", supplier);
            strcat(sql_str, supplier_cat);
        }
    }

    //  查询数据库
    char **result = nullptr;
    int row = 0;
    int column = 0;
    char *errmsg = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }

    for (int i = 1; i <= row; i++)
    {
        bzero(ret_msg, sizeof(ret_msg));
        for (int j = 0; j < column; j++)
        {
            // printf("%s\t", result[(column * i) + j]);
            strcat(ret_msg, result[(column * i) + j]);
            strcat(ret_msg, "|");
        }
        strcat(ret_msg, "\n");

        //  发送 修改用户权限 结果
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
    }

    char operation[32] = "";
    sprintf(operation, "CHECK_ITEMS");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, item, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 查看历史记录 功能
void deal_CHECK_HISTORY(char *buff, client_info &cli, char *name)
{
    //  先确定当前登录用户是否是管理员权限
    //  若不是管理员权限,则不将所有信息返回
    bool flag = false;
    //  SQL语句
    char sql_str[256];
    char ret_msg[512];
    //  查询这个人的权限
    sprintf(sql_str, "select privilege from user where uname='%s';", name);
    char **result = nullptr;
    int row = 0;
    int column = 0;
    char *errmsg = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }
    //  有这个人,且权限为管理员权限
    if (row != 0 && strcmp(result[column], "admin") == 0)
    {
        flag = true;
    }

    //  获取客户端发来的消息,并进行拆分
    char *uname = buff + 1;
    char *item = uname + 1 + (strlen(uname));

    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "select * from history ");
    //  如果 用户名, 或物品,有任何一个存在,则加上where
    if (strcmp(uname, "") || strcmp(item, "") || !flag)
    {
        strcat(sql_str, "where ");
    }

    if (flag)
    {
        if (strcmp(uname, ""))
        {
            char uname_cat[32] = "";
            sprintf(uname_cat, "uname='%s' ", uname);
            strcat(sql_str, uname_cat);

            if (strcmp(item, ""))
            {
                char item_cat[32] = "";
                sprintf(item_cat, "and Obj='%s' ", item);
                strcat(sql_str, item_cat);
            }
        }
        else
        {
            if (strcmp(item, ""))
            {
                char item_cat[32] = "";
                sprintf(item_cat, "Obj='%s' ", item);
                strcat(sql_str, item_cat);
            }
        }
    }
    else
    {
        uname = name;
        char name_cat[32] = "";
        sprintf(name_cat, "uname='%s' ", name);
        strcat(sql_str, name_cat);

        if (strcmp(item, ""))
        {
            char item_cat[32] = "";
            sprintf(item_cat, "and Obj='%s' ", item);
            strcat(sql_str, item_cat);
        }
    }

    //  查询数据库
    char **result2 = nullptr;
    row = 0;
    column = 0;
    char *errmsg2 = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result2, &row, &column, &errmsg2) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }

    for (int i = 1; i <= row; i++)
    {
        bzero(ret_msg, sizeof(ret_msg));
        for (int j = 0; j < column; j++)
        {
            // printf("%s\t", result[(column * i) + j]);
            strcat(ret_msg, result2[(column * i) + j]);
            strcat(ret_msg, "|");
        }
        strcat(ret_msg, "\n");

        //  发送 修改用户权限 结果
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
    }

    char operation[32] = "";
    sprintf(operation, "CHECK_HISTORY");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, uname, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 查询所有用户 功能
void deal_FIND_ALL_USER(char *buff, client_info &cli, char *name)
{
    char *uname = buff + 1;
    char *privilege = uname + 1 + strlen(uname);

    char sql_str[256];
    char ret_msg[512] = "CHECK_FAILURE";
    //  先加上查看的用户的权限
    sprintf(sql_str, "select * from user where privilege='%s' ", privilege);
    //  用户名
    if (strcmp(uname, ""))
    {
        char uname_cat[32] = "";
        sprintf(uname_cat, "and uname='%s' ", uname);
        strcat(sql_str, uname_cat);
    }

    //  查询数据库
    char **result = nullptr;
    int row = 0;
    int column = 0;
    char *errmsg = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }

    for (int i = 1; i <= row; i++)
    {
        bzero(ret_msg, sizeof(ret_msg));
        for (int j = 0; j < column; j++)
        {
            // printf("%s\t", result[(column * i) + j]);
            strcat(ret_msg, result[(column * i) + j]);
            strcat(ret_msg, "|");
        }
        strcat(ret_msg, "\n");

        printf("ret_msg = %s",ret_msg);

        //  发送 修改用户权限 结果
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
    }

    char operation[32] = "";
    sprintf(operation, "FIND_USER");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, uname, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 修改权限 功能
void deal_CHANGE_PRIVILEGE(char *buff, client_info &cli, char *name)
{
    char *uname = buff + 1;

    char sql_str[256];
    char ret_msg[64] = "CHANGE_PRIVILEGE_FAILURE";
    /*
     *  不可对ROOT权限用户操作
     */
    if (!strcmp(uname, ROOT))
    {
        //  发送 删除用户
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
        return;
    }

    //  先检查有没有这个用户,没有就返回 修改错误
    sprintf(sql_str, "select * from user where uname='%s';", uname);
    if (select_data_ret_num(sql_str, sqldb) != 0)
    {
        bzero(sql_str, sizeof(sql_str));
        //  修改
        sprintf(sql_str, "update user set privilege='admin' where uname='%s';", uname);
        if (0 == insert_data(sql_str, sqldb))
        {
            bzero(ret_msg, sizeof(ret_msg));
            strcpy(ret_msg, "CHANGE_PRIVILEGE_SUCESS");
        }
    }

    //  发送 修改用户权限 结果
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    char operation[32] = "";
    sprintf(operation, "CHANGE_PRIVILEGE");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, uname, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 删除用户 功能
void deal_DELETE_USER(char *buff, client_info &cli, char *name)
{
    char *uname = buff + 1;

    char sql_str[256];
    char ret_msg[64] = "DELETE_USER_FAILURE";

    /*
     *  不可对ROOT权限用户操作
     */
    if (!strcmp(uname, ROOT))
    {
        //  发送 删除用户
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
        return;
    }

    //  先检查有没有这个用户,没有就返回 删除错误
    sprintf(sql_str, "select * from user where uname='%s';", uname);
    if (select_data_ret_num(sql_str, sqldb) != 0)
    {
        bzero(sql_str, sizeof(sql_str));
        //  删除
        sprintf(sql_str, "delete from user where uname='%s';", uname);
        if (0 == insert_data(sql_str, sqldb))
        {
            bzero(ret_msg, sizeof(ret_msg));
            strcpy(ret_msg, "DELETE_USER_SUCESS");
        }
    }

    //  发送 删除用户 结果
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    char operation[32] = "";
    sprintf(operation, "DELETE_USER");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, uname, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 修改密码 功能
void deal_CHANGE_PASSWD(char *buff, client_info &cli, char *name)
{
    char *uname = buff + 1;
    char *pwd = buff + 2 + (strlen(buff + 1));
    char *new_pwd = pwd + 1 + strlen(pwd);

    //  先查看用户名和密码对不对
    char sql_str[256];
    sprintf(sql_str, "select * from user where uname='%s' and passwd='%s';", uname, pwd);

    char ret_msg[64] = "CHANGE_PASSWD_FAILURE";

    /*
     *  不可对ROOT权限用户操作
     */
    if (!strcmp(uname, ROOT))
    {
        //  发送 删除用户
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
        return;
    }

    //  如果这个用户名和密码都正确对应,则进行修改
    if (0 != select_data_ret_num(sql_str, sqldb))
    {
        bzero(sql_str, sizeof(sql_str));
        sprintf(sql_str, "update user set passwd='%s' where uname='%s' and passwd='%s';", new_pwd, uname, pwd);
        if (0 == insert_data(sql_str, sqldb))
        {
            strcpy(ret_msg, "CHANGE_PASSWD_SUCCESS");
        }
    }

    //  发送 存放结果
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    char operation[32] = "";
    sprintf(operation, "CHANGE_PASSWD_to_[%s]", new_pwd);
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, uname, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));

    insert_data(sql_str, sqldb);
}

//  处理 查看 个人信息 功能
void deal_CHECK_INFO(char *buff, client_info &cli, char *name)
{
    char *uname = buff + 1;
    char ret_msg[128] = "CHECK_FAILURE";
    //  俩名字不相同
    if (strcmp(uname, name) != 0)
    {
        if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
        {
            ERR_MSG("send");
            return;
        }
        return;
    }

    //  根据名字查询权限和注册时间
    char sql_str[256];
    sprintf(sql_str, "select privilege,signin_time from user where uname='%s';", uname);

    char **result = nullptr;
    int row = 0;
    int column = 0;
    char *errmsg = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }

    bzero(ret_msg, sizeof(ret_msg));
    sprintf(ret_msg, "%s|%s", result[2], result[3]);
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    //  存入历史记录
    char operation[32] = "";
    sprintf(operation, "CHECK_INFO");
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, name, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理 取出物品 功能
void deal_GET_OUT(char *buff, client_info &cli, char *name)
{
    char *item = buff + 1;
    char *supplier = buff + 2 + (strlen(buff + 1));
    int num = *((int *)(supplier + 1 + (strlen(supplier))));

    //  先查看里面有没有这么一个东西,以及这个东西是不是>=要取出的数
    char sql_str[256];
    char ret_msg[64] = "GET_OUT_FAILURE";
    sprintf(sql_str, "select * from item_info where item_name='%s' and supplier='%s' and numb>=%d;", item, supplier, num);
    //  表中有这个东西,且库存充足
    if (select_data_ret_num(sql_str, sqldb) != 0)
    {

        bzero(sql_str, sizeof(sql_str));
        sprintf(sql_str, "update item_info set numb=numb-%d where item_name='%s' and supplier='%s';",
                num, item, supplier);
        if (insert_data(sql_str, sqldb) != -1)
        {
            strcpy(ret_msg, "GET_OUT_SUCESS");
        }
    }

    //  发送 取出物品结果
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    //  存储历史记录
    char operation[256] = "";
    sprintf(operation, "GET_OUT_%s_%s_%d", supplier, item, num);
    char now_time[64] = "";
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, item, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);

    //  将数量为0的物品记录清空
    bzero(sql_str, sizeof(sql_str));
    sprintf(sql_str, "delete from item_info where numb=0;");
    insert_data(sql_str, sqldb);
}

//  处理 存放物品 功能
void deal_SAVE(char *buff, client_info &cli, char *name)
{
    char *item = buff + 1;
    char *supplier = buff + 2 + (strlen(buff + 1));
    int num = *((int *)(supplier + 1 + (strlen(supplier))));

    //  先查看里面有没有这么一个东西
    char sql_str[256];
    sprintf(sql_str, "select * from item_info where item_name='%s' and supplier='%s';", item, supplier);

    char ret_msg[64] = "SAVE_FAILURE";
    int row = select_data_ret_num(sql_str, sqldb);

    bzero(sql_str, sizeof(sql_str));
    //  没有这个东西,向里面插入数据
    char now_time[64] = "";
    if (row == 0)
    {
        sprintf(sql_str, "insert into item_info (item_name,supplier,numb,input_name,input_time) values('%s','%s',%d,'%s','%s');",
                item, supplier, num, name, get_time(now_time));
    }
    //  有这个东西,更新数据
    else
    {
        sprintf(sql_str, "update item_info set numb=numb+%d where item_name='%s' and supplier='%s';",
                num, item, supplier);
    }

    //  是否修改存放结果
    if (0 == insert_data(sql_str, sqldb))
    {
        strcpy(ret_msg, "SAVE_SUCESS");
    }

    //  发送 存放结果
    if (send(cli.new_fd, &ret_msg, strlen(ret_msg), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    //  向历史记录表中插入数据
    char operation[256] = "";
    sprintf(operation, "SAVE_%s_%s_%d", supplier, item, num);
    bzero(now_time, sizeof(now_time));
    memset(sql_str, 0, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, item, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理登录功能
void deal_LOGIN(char *buff, client_info &cli, char *uname)
{
    char *name = buff + 1;
    strcpy(uname, name);

    char *pwd = buff + 2 + (strlen(buff + 1));

    //  SQL语句
    char sql_str[256];
    sprintf(sql_str, "select privilege from user where uname='%s' and passwd='%s';", name, pwd);

    //  查询是否有这个人
    char **result = nullptr;
    int row = 0;
    int column = 0;
    char *errmsg = nullptr;
    if (sqlite3_get_table(sqldb, sql_str, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "sqlite3_get_table error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), sqlite3_errmsg(sqldb), __LINE__);
        return;
    }

    char ret[128];
    //  没有这个人,登录失败,有则根据权限发回对应的字符串
    if (row == 0)
    {
        strcpy(ret, "LOGIN_OR_SIGNIN_FAILURE");
    }
    else if (strcmp(result[column], "user") == 0)
    {
        strcpy(ret, "LOGIN_OR_SIGNIN_SUCCESS");
    }
    else if (strcmp(result[column], "admin") == 0)
    {
        strcpy(ret, "ADMIN_LOGIN_SUCESS");
    }

    //  容器不为空,且能够找到这个元素,那么返回登录失败,因为他正在登录
    if (!signin_set.empty() && signin_set.find(name) != signin_set.end())
    {
        strcpy(ret, "LOGIN_OR_SIGNIN_FAILURE");
    }
    else
    {
        signin_set.insert(name);
    }

    //  向客户端发送消息
    //  发送
    if (send(cli.new_fd, &ret, strlen(ret), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    //  向历史记录表中插入数据
    char operation[16] = "LOGIN";
    char now_time[64] = "";
    memset(sql_str, 0, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            uname, operation, name, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

//  处理注册功能
void deal_SIGNIN(char *buff, client_info &cli)
{
    char *name = buff + 1;
    char *pwd = buff + 2 + (strlen(buff + 1));

    char sql_str[256];
    sprintf(sql_str, "select * from user where uname='%s';", name);
    //  查询是否有这个人
    int row = select_data_ret_num(sql_str, sqldb);

    char ret[128] = "LOGIN_OR_SIGNIN_FAILURE";

    //  没有这个人,进行注册,向用户表中插入数据
    if (row == 0)
    {
        strcpy(ret, "LOGIN_OR_SIGNIN_SUCCESS");

        //  向用户表中插入数据
        memset(sql_str, 0, sizeof(sql_str));
        char now_time[64] = "";
        sprintf(sql_str, "insert into user (uname,passwd,privilege,signin_time) values('%s','%s','user','%s');", name, pwd, get_time(now_time));
        insert_data(sql_str, sqldb);
    }
    //  发送 注册成功信号
    if (send(cli.new_fd, &ret, strlen(ret), 0) < 0)
    {
        ERR_MSG("send");
        return;
    }

    //  向历史记录表中插入数据
    char operation[16] = "SIGIN";
    char now_time[64] = "";
    memset(sql_str, 0, sizeof(sql_str));
    sprintf(sql_str, "insert into history (uname,operation,Obj,optime,oper_ip) values('%s','%s','%s','%s','%s');",
            name, operation, name, get_time(now_time), inet_ntoa(cli.c_in.sin_addr));
    insert_data(sql_str, sqldb);
}

// 获取当前时间,返回字符串
char *get_time(char *now_time)
{
    time_t t;
    struct tm *info = NULL;
    time(&t);
    info = localtime(&t);
    sprintf(now_time, "%d-%02d-%02d %02d:%02d:%02d",
            info->tm_year + 1900, info->tm_mon + 1, info->tm_mday,
            info->tm_hour, info->tm_min, info->tm_sec);
    return now_time;
}

// 插入数据
int insert_data(char *sql_str, sqlite3 *sqldb)
{
    char *error_msg = NULL;

    if (sqlite3_exec(sqldb, sql_str, NULL, NULL, &error_msg) != SQLITE_OK)
    {
        fprintf(stderr, "insert into TABLE error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), error_msg, __LINE__);
        return -1;
    }
    return 0;
}

// 查询数据
int select_data_ret_num(char *sql_str, sqlite3 *sqldb)
{
    char *error_msg = NULL;
    char **pres = NULL;
    int row, column;

    if (sqlite3_get_table(sqldb, sql_str, &pres, &row, &column, &error_msg) != SQLITE_OK)
    {
        fprintf(stderr, "select_data_ret_num error : %d : %s     __%d__\n",
                sqlite3_errcode(sqldb), error_msg, __LINE__);
        return 0;
    }
    return row;
}

makefile

EXE=server
CC=g++
CFLAGs=-c
FLAG+=-lsqlite3
FLAG+=-lpthread
OBJs+=main.o
OBJs+=server.o
all:$(EXE)
$(EXE):$(OBJs)
	$(CC) $^ -o $@ $(FLAG)
%.o:%.cpp
	$(CC) $(CFLAGs) $^ -o $@
clean:
	rm *.o $(EXE)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1184472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[HCTF 2018]WarmUp最详细解释

查看源码找到提示 访问source.php 代码审计&#xff1a; class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php"]; 定义了一个名为emmm的类&#xff0c;在该类中有…

[unity]切换天空盒

序 unity是自带天空盒的&#xff1a; 但有的时候不想用自带的。怎么自定义&#xff1f;如何设置&#xff1f; 官方文档 Unity - Manual: The Lighting window (unity3d.com) 相关窗口的打开方法 天空盒对应的选项 实际操作 从标准材质球到天空盒材质球 新建一个材质球&…

每日一题 2609. 最长平衡子字符串(简单)

乍一看&#xff0c;简单题&#xff0c;思路也很简单&#xff0c;但代码有点不好写 思路无非就是从找到的第一个 ‘0’ 开始&#xff0c;一直找 ‘0’ 知道遇到一个 ‘1’&#xff0c;此时变换策略&#xff0c;一直找 ‘1’&#xff0c;知道遇到一个 ‘0’&#xff0c;就这样一…

掌握 Figma 的自动布局,轻松设计 - 简化指南!

Figma作为一种基于浏览器操作的设计工具&#xff0c;改变了传统的设计软件工作模式&#xff0c;为我们在线合作设计奠定了基础。自推出以来&#xff0c;Figma的创新一直受到国内外众多UI设计师的关注&#xff0c;包括在推动设计团队开展高效设计工作方面&#xff0c;Figma推出了…

计算机毕业设计基于springboot+java+vue的健身房课程预约信息网站

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 项目介绍 本健身网…

win10安装.net3.5

运行 winver 对应Windows的版本下载相应的iso&#xff0c;可以在MSDN, 我告诉你 - 做一个安静的工具站 (itellyou.cn)下载&#xff0c;最新的去微软官方下载下载 Windows 10 (microsoft.com) 下载这个工具下载 将iso中的文件夹sxs里的内容拷贝到C:/windows/sxs里 管理员运行po…

超简单超实用的网页视频下载方法

想必大家经常需要下载网页视频&#xff0c;以便自己离线观看&#xff0c;这篇文章就来说一种超简单超实用的快捷方法&#xff0c;无需下载软件&#xff0c;无需使用插件&#xff0c;三四步轻松搞定&#xff01; 目录 Google浏览器网页视频下载 Microsoft Edge浏览器网页视频…

前端项目导入vue和element

1.安装nodejs 下载链接https://cdn.npmmirror.com/binaries/node/v18.18.0/node-v18.18.0-x64.msi 进入cmd 命令行模式 管理员身份运行 输入 &#xff08;node -v&#xff09;能看到版本号 npm config set prefix "C:\Program Files\nodejs" 默认路径 npm config…

网页【CSS】滚动条

前言 优化后的滚动条会提亮我们的网站页面。 例如&#xff1a;CSS-TRICKS这个网站如果采用的是浏览器默认的滚动条&#xff0c;不进行优化&#xff0c;页面会显得很不搭。 所以该网站的滚动条样式优化如下&#xff1a; html::-webkit-scrollbar {width: 30px;height: 30px; …

基于Springboot的时装购物系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的时装购物系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

notepad++搜索结果窗口不见了

1、使用notepad打开一个文件文件 2、ctrlf&#xff0c;打开搜索窗口&#xff0c;随便搜索一个内容 3、按F7,然后AltF7 切换焦点到Find result. 会有一个小窗口出现&#xff0c;内容是&#xff1a;还原&#xff0c;移动&#xff0c;大小等 4&#xff0c;点移动&#xff0c;使…

打造高效的客服体系,就在于这个“专属链接”

想要追踪特定数据&#xff0c;但是得在数据库中大海捞针&#xff1f; 想要知道某个推广的效果&#xff0c;但是无法追踪&#xff1f; 想要获得个性化的报告&#xff0c;但是数据不够精准&#xff1f; 面对这些情况&#xff0c;只需要靠一条“专属链接”就能一一击破&#xff…

WebGL的技术难点分析

WebGL是一项强大的技术&#xff0c;但在开发过程中可能会遇到一些挑战和技术难点。以下是一些与WebGL相关的技术难点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.3D数学和图形编程&#xff1a;理…

数据可视化PCA与t-SNE

PCA&#xff08;主成分分析&#xff09;和t-SNE&#xff08;t分布随机近邻嵌入&#xff09;都是降维技术&#xff0c;可以用于数据的可视化和特征提取。 降维&#xff1a;把数据或特征的维数降低&#xff0c;其基本作用包括&#xff1a; 提高样本密度&#xff0c;以及使基于欧…

将idea默认折叠的注释打开

idea默认的代码注释是折叠的&#xff0c;不方便查看 下面是改成默认打开的步骤 1、打开settings 2、找到Code Folding,将 Annotations前面的 对钩去掉&#xff0c;保存即可

【C++初阶(五)类和对象(上)】

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

Flink 基础 -- 尝试Flink

官网 文档 v1.18.0 下载 数据流上的状态计算(Stateful Computations over Data Streams) Apache Flink是一个框架和分布式处理引擎&#xff0c;用于无界和有界数据流的有状态计算。Flink被设计成可以在所有常见的集群环境中运行&#xff0c;以内存中的速度和任何规模执行计…

实验(一):运算器实验

一、实验内容与目的 实验要求&#xff1a; 利用 CP226 实验仪的 K16..K23开关做为DBUS数据&#xff0c;其它开关做为控制信号&#xff0c;将数据写累加器A和工作寄存器W&#xff0c;并用开关控制ALU的运算方式&#xff0c;实现运算器的功能&#xff0c;将结果送入OUT寄存器。 实…

软件工程第十周

测试过程 单元测试 注意出错处理&#xff01;单元测试的数据处理部分请见Junit 单元测试之错误和异常处理-CSDN博客 单元测试准则 白盒&#xff1a;对系统结构非常清楚&#xff01;就像大题注重过程。 单元测试的测试环境 一定要保证整个环境是完整的&#xff0c;尽管可能没…