基于数据库 Sqlite3 的 root 管理系统

这篇具有很好参考价值的文章主要介绍了基于数据库 Sqlite3 的 root 管理系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.服务器

1.1服务器函数入口

#include "server.h"

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

    char buf[128] = {0};
    char buf_ID[256] = {0};
    // 接收报错信息判断
    sqlite3 *db;
    // 创建员工信息的表格,存在则打开
    db = Sqlite_Create();
    if (db == NULL)
    {
        printf("sqlite_create=NULL\n");
        return 0;
    }

    // 服务器 套接字->端口重启->绑定->监听
    int sock_fd = sock_listen();
    if (!sock_fd)
    {
        printf("流程出现故障%d\n", __LINE__);
        return 0;
    }
    // 创建红黑树根节点
    //  创建一个epoll句柄/红黑树根节点
    epfd = epoll_create(10);

    if (epfd < 0)
    {
        printf("epoll_create on_success _%d_", __LINE__);
        return 0;
    }
    // 添加监听连接事件到红黑树节点中
    add_epoll(epfd, sock_fd);

    // 到此,以上流程全部正确走完
    // 客户端信息结构体的大小
    socklen_t addrlen = sizeof(my_cin);

    /*********与客户端互动区域_begin*********/
    // 存储连接的所有客户端描述符
    // str_newfd *arr_newfd;

    // arr_newfd->len
    // 新连接的客户端返回的描述符
    int newfd = -1;
    // 最下的客户端描述符

    int midfd = -1;
    ser_cli my_ser_cli;
    str_staff my_str_staff;

    while (1)
    {

        // ret返回就绪事件的个数,并将就绪的事件放入到
        // events这个结构体中,参3表示最多放入10个事件,
        // 参4的-1表示不关心是否超时
        int ret = epoll_wait(epfd, events, 10, -1);
        if (ret < 0 || ret > 10)
        {
            printf("epoll_wait on_success:%d\n", __LINE__);
            return 0;
        }
        /****走到这里,表示有事件准备就绪****/
        for (int i = 0; i < ret; i++)
        {
            
            // 客户端连接事件发生
            if (events[i].data.fd == sock_fd)
            {
                newfd = accept(sock_fd, (struct sockaddr *)&my_cin, &addrlen);
                if (newfd < 0)
                {
                    ERR_MSG("accept");
                    return -1;
                }
                if (add_epoll(epfd, newfd) < 0)
                {
                    printf("add_epoll errno%d\n", __LINE__);
                    return 0;
                }
                printf("newfd=%d连接成功\n", newfd);
                // 判断新描述符的大小,放入到顺序表中
                //  pai_arr_newfd(arr_newfd,newfd);
            }
            else
            {
                ser_cli my_ser_cli;
                str_staff my_str_staff;
                // 创建一个线程
                pthread_t tid;
                my_ser_cli.fd = events[i].data.fd;
                // 接收客户端数据,进入账号密码的判断,是root还是普通
                // 接收服务器的信息
                int ser_fd=my_ser_cli.fd;
                if (recv(my_ser_cli.fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
                {
                    printf("接收失败%d\n", __LINE__);
                    return 0;
                }
                if (my_ser_cli.CLI_SELECT == 3) // 用户选择退出
                {
                    
                    quit(my_ser_cli);
                }
                // 往下走说明是用户和root登陆
                // 当事件发生以后移除文件描述符
                my_ser_cli.events_i = i;
                my_ser_cli.db = db;
                my_ser_cli.fd = ser_fd;
                if (pthread_create(&tid, NULL, callBack, (void *)&my_ser_cli) != 0)
                {
                    printf("%ld线程创建失败%d\n", tid, __LINE__);
                    return 0;
                }
                remove_fd(&my_ser_cli);//账号下线,清楚其存在
            }
        }
    }
    /*********与客户端互动区域_end*********/
    // 释放资源
    return 0;
}

1.2服务器运行代码

#include "server.h"
int flag = 0;
int fd_flag = 0;
// 创建数据库并打开数据表
sqlite3 *Sqlite_Create(void)
{
    /*表格信息: 1.主键(int id),用于判断该账号是用户还是管理员
                 2.员工姓名(char name)
                 2.员工工号(int jobnumner)
                 3.员工年龄(int age)
                 4.当前薪资(float wage)
                 5.岗位名称(char post)
                 6.手机号(int phone )
                 7.入职时间 (char time)精确到日
                 8.是否在线 (state int) 1表示在线 0不在线*/
    // 存储SQL的报错信息
    char *errmsg = NULL;
    // 创建并打开数据库
    sqlite3 *db = NULL;
    if (sqlite3_open("./staff.db", &db) != SQLITE_OK)
    {
        printf("sqlite3_open errno %d\n", __LINE__);
        return NULL;
    }
    debuf_db = db;
    // 组装SQL语句创建数据表
    char sql[528] = "create table if not exists staff(id int,name char,jobnumber int,age int,wage float,post char,phone int,time char,state int,pass_w int);";
    if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "__%d__ sqlite3_exec: %s\n", __LINE__, errmsg);
        return NULL;
    }
    return db;
}

// 服务器 套接字->端口重启->绑定->监听
int sock_listen(void)
{
    // 一.创建套接字1.AF_INET默认为ip(7)协议 2.SOCK_STREAM默认为TCP
    // 3.0表示使用type对应的默认协议
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0)
    {
        ERR_MSG("socket");
        goto OUT1;
    }

    // 端口快速启用
    int resue = 1;
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &resue, sizeof(resue)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    // 填充服务器信息结构体
    my_ser.sin_family = AF_INET;            // IPv4协议指向填充
    my_ser.sin_port = htons(PORT);          // 将端口转换成网络字节
    my_ser.sin_addr.s_addr = inet_addr(IP); // IP地址转换成网络字节序
    // 绑定服务器的IP和端口
    if (bind(sock_fd, (struct sockaddr *)&my_ser, sizeof(my_ser)) < 0)
    {
        ERR_MSG("bind");
        goto OUT2;
    }
    // 将套接字设置为被动监听,最多监听128个
    if (listen(sock_fd, 128) < 0)
    {
        ERR_MSG("listen");
        goto OUT2;
    }
    return sock_fd;
OUT2:
    close(sock_fd);
OUT1:
    return 0;
}
// 红黑树监听事件信息的添加
int add_epoll(int epfd, int fd)
{
    // 将套接字的信息存入到event结构体中,为事件放入红黑树中做准备
    event.events = EPOLLIN; // 关注可读事件,套接字有数据可读时触发
    event.data.fd = fd;
    // 将event存放到套接字信息放入到红黑树中
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event) < 0)
    {
        printf("epoll_ctl on_success _%d_", __LINE__);
        return 0;
    }
    return 1;
}
int remove_epoll(int epfd, int fd)
{
    // 将套接字的信息存入到event结构体中,为事件放入红黑树中做准备
    event.data.fd = fd;
    // 将event存放到套接字信息放入到红黑树中

    if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0)
    {
        ERR_MSG("epoll_ctl");
        return 0;
    }
    return 1;
}
// 客户端的描述符在顺序表中添加后的排序
//  void paixu_arr_newfd(str_newfd *arr_newfd,int newfd)
//  {
//      int i,j,count;
//      arr_newfd->arr[arr_newfd->len].fd=newfd;
//      arr_newfd->len++;
//      for(i=1;i<=arr_newfd->len;i++)
//      {
//          count=0;
//          for(j=0;j<arr_newfd.)
//      }
//  }
// 资源的释放函数

// 创建一个线程处理客户端交互
void *callBack(void *arg)
{
    // 组装SQL语句
    char sql[256] = "";
    char **pres = NULL;
    int row, column;
    char *errmsg;
    int jobnumber, pass_w;
    ser_cli *my_ser_cli = (ser_cli *)arg;
    char debug[128] = "kkk";
    ser_cli my_ser_cli_C = *my_ser_cli;
    // 判断账号是否存在
    sprintf(sql, "select * from staff where jobnumber=%d;", my_ser_cli->staff_information.jobnumber);
    // printf("%s%d\n", debug,__LINE__);
    if (sqlite3_get_table(my_ser_cli->db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
    {
        printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
        return 0;
    }
    else
    {
        if (row == 0)
        {
            // 账号不存在
            my_ser_cli->cli_n_p = 1; // 该位写1账号不存在
            my_ser_cli_C = *my_ser_cli;
            send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);

            return 0;
        }
        // 判断密码是否与账号匹配
        sprintf(sql, "select * from staff where jobnumber=%d and pass_w=%d;", my_ser_cli->staff_information.jobnumber, my_ser_cli->staff_information.pass_w);
        if (sqlite3_get_table(my_ser_cli->db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("get_table_pass_w error %d\n", __LINE__);
            return 0;
        }
        else
        {
            if (row == 0)
            {
                // 账号错误
                my_ser_cli->cli_n_p = 2; // 账号匹配密码不正确s
                my_ser_cli_C = *my_ser_cli;
                printf("密码不正确\n");
                send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);
                return 0;
            }
            else // 判断是root还是用户
            {
                // 判断用户还是root
                sprintf(sql, "select * from staff where id=%d;", my_ser_cli->staff_information.key);
                if (sqlite3_get_table(my_ser_cli->db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
                {
                    printf("get_table_pass_w error %d\n", __LINE__);
                    return 0;
                }
                else

                {

                    if (row == 0 && my_ser_cli->CLI_SELECT == 1) // 管理员进错到用户
                    {

                        my_ser_cli->cli_n_p = 3; // 管理员进错到用户
                        my_ser_cli_C = *my_ser_cli;
                        send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);
                        return 0;
                    }
                    else if (row == 0 && my_ser_cli->CLI_SELECT == 2) // 用户不能访问管理
                    {

                        my_ser_cli->cli_n_p = 4; // 用户不能访问管理
                        my_ser_cli_C = *my_ser_cli;
                        send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);
                        return 0;
                    }
                    if (remove_epoll(epfd, my_ser_cli->fd) == 0)
                    {
                        printf("remove_epoll errno%d\n", __LINE__);
                        my_ser_cli->cli_n_p = 1; // 用户不能访问管理
                        my_ser_cli_C = *my_ser_cli;
                        send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);
                        return 0;
                    }
                    // 走到这里,表示均匹配成功
                    my_ser_cli->cli_n_p = 5;
                    // 将员工号存到数组里,用于历史记录查询
                    add_jobnumber_A(my_ser_cli);
                    my_ser_cli_C = *my_ser_cli;
                    if(add_fd(my_ser_cli)==0)//判断账号是否重复登陆
                    {
                        //表示账号属于重复登陆
                        my_ser_cli_C.flag=0;//告诉客户端重复登陆
                        send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);
                        return 0;
                    }
                    my_ser_cli_C.flag=1;//告诉客户端没有重复登陆
                    printf("%d %d\n",my_ser_cli_C.flag,__LINE__);
                    send(my_ser_cli->fd, &my_ser_cli_C, sizeof(my_ser_cli_C), 0);//走到这里,表示客户端连接成功
                    while (1)
                    {

                        switch (my_ser_cli->CLI_SELECT)
                        {
                        case 1: // 控制管理员界面
                            if (root_ui(my_ser_cli) == 0)
                            {
                                pthread_detach(tid);
                                return 0;
                            }
                            break;
                        case 2: // 员工管理员界面
                            if (user_ui(my_ser_cli) == 0)
                            {
                                return 0;
                            }
                            break;
                        default:
                            break;
                        }
                    }
                }
            }
        }
        return 0;
    }

    return 0;
}
// 员工历史记录添加
int add_jobnumber_A(ser_cli *my_ser_cli_H)
{
    // 重新保存
    ser_cli my_ser_cli = *my_ser_cli_H;
    jobnumber_A[0].flag = flag++; // 存放下一次新的工号存储位置
    printf("flag=%d\n", flag);
    // 判断该账号是否以及存在于数组
    for (int i = 0; i < 10; i++)
    {
        if (jobnumber_A[i].staff_information.jobnumber == my_ser_cli.staff_information.jobnumber) // 已经在数组中
        {
            return 0; // 不做添加
        }
    }
    // 走到这里表示该账号不存在数组中,添加
    jobnumber_A[jobnumber_A[0].flag].staff_information.jobnumber = my_ser_cli.staff_information.jobnumber;
}
int root_ui(ser_cli *my_ser_cli)
{
    char sql[528] = "";
    ser_cli my_ser_cli_ui;
    ser_cli my_ser_cli_ui_1; // 除case1以外使用的
    str_staff my_str_staff;
    // my_ser_cli_ui.staff_information = my_str_staff;
    my_ser_cli_ui.fd = my_ser_cli->fd;
    printf("\n管理%d进入root界面%d\n", my_ser_cli->staff_information.jobnumber, __LINE__);
    char **pres = NULL;
    int row, column;
    char *errmsg;
    int jobnumber, pass_w;
    // 接收管理员操作指令码
    while (1)
    {
        my_ser_cli_ui.staff_information.jobnumber = 0;
        if (recv(my_ser_cli->fd, &my_ser_cli_ui, sizeof(my_ser_cli_ui), 0) < 0)
        {

            ERR_MSG("recv");
            return 0;
        }
        my_ser_cli_ui_1 = my_ser_cli_ui; // 备份,防止2345的操作影响到1
        my_ser_cli_ui_1.db = my_ser_cli->db;
        my_ser_cli_ui_1.fd = my_ser_cli->fd;
        switch (my_ser_cli_ui.CLI_SELECT_H)
        {
        case 1: // 添加员工信息
                // 判断账号是否存在
            sprintf(sql, "select * from staff where jobnumber=%d;", my_ser_cli_ui.staff_information.jobnumber);
            // printf("%s%d\n", debug,__LINE__);
            if (sqlite3_get_table(my_ser_cli->db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
            {
                printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
                return 0;
            }
            if (row != 0) // 表示工号已经存在
            {
                my_ser_cli_ui.CLI_SELECT = 1;
                if (send(my_ser_cli->fd, &my_ser_cli_ui, sizeof(my_ser_cli_ui), 0) < 0)
                {
                    ERR_MSG("recv");
                    return 0;
                }
                return 0;
            }
            if (my_ser_cli->staff_information.jobnumber)
            {
                sprintf(sql, "insert into staff values (%d, '%s', %d, %d, %f, '%s', %d, '%s', %d, %d);", my_ser_cli_ui.staff_information.key,
                        my_ser_cli_ui.staff_information.name, my_ser_cli_ui.staff_information.jobnumber, my_ser_cli_ui.staff_information.age, my_ser_cli_ui.staff_information.wage,
                        my_ser_cli_ui.staff_information.post, my_ser_cli_ui.staff_information.phone, my_ser_cli_ui.staff_information.time, my_ser_cli_ui.staff_information.state,
                        my_ser_cli_ui.staff_information.pass_w);
                if (sqlite3_exec(my_ser_cli->db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    fprintf(stderr, "__%d__ sqlite3_exec: %s\n", __LINE__, errmsg);
                    return 0;
                }

                // 告诉客户端注册完毕
                if (send(my_ser_cli->fd, &my_ser_cli_ui, sizeof(my_ser_cli_ui), 0) < 0)
                {
                    ERR_MSG("recv");
                    return 0;
                }
            }
            break;

        case 2:
            root_xiugai_ser(&my_ser_cli_ui_1); // 修改员工信息
            break;
        case 3:
            root_chaxun_user(&my_ser_cli_ui_1); // 查询员工信息
            break;
        case 4:
            root_lishi_user(&my_ser_cli_ui_1); // 发送历史查询记录
            break;
        case 5:
            printf("管理系统退出成功\n");
            return 0;
            break;
        default:
            printf("输入错误,请重新输入\n");
            return 0;
            break;
        }
    }
}
// 服务器向root发送历史记录表
int root_lishi_user(ser_cli *my_ser_cli_H)
{
    printf("root调用历史信息表\n");
    char **pres = NULL;
    int row, column;
    char *errmsg = NULL;
    int jobnumber, pass_w;
    char sql[528] = "";
    int index = 10;
    printf("flag_A=%d\n", flag);
    for (int i = 0; i < flag; i++)
    {
        // 将存在的所有放到数组里面
        memset(sql, '0', sizeof(sql));
        sprintf(sql, "select * from staff where jobnumber=%d;", jobnumber_A[i].staff_information.jobnumber);
        if (sqlite3_get_table(my_ser_cli_H->db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
            return 0;
        }
        if (row == 0) // 表示没有找到,向服务器发送信息
        {
            printf("出现错误 工号不存在%d\n", __LINE__);
        }
        else
        {
            // 走到这里表示工号存在,将员工信息填充发送带客户端
            // 发送

            jobnumber_A[i].staff_information.key = atoi(pres[index++]);
            strcpy(jobnumber_A[i].staff_information.name, pres[index++]);
            jobnumber_A[i].staff_information.jobnumber = atoi(pres[index++]);
            jobnumber_A[i].staff_information.age = atoi(pres[index++]);
            jobnumber_A[i].staff_information.wage = atof(pres[index++]);
            strcpy(jobnumber_A[i].staff_information.post, pres[index++]);
            jobnumber_A[i].staff_information.phone = atoi(pres[index++]);
            strcpy(jobnumber_A[i].staff_information.time, pres[index++]);
            jobnumber_A[i].staff_information.state = atoi(pres[index++]);
            jobnumber_A[i].staff_information.pass_w = atoi(pres[index++]);
        }
        if (send(my_ser_cli_H->fd, jobnumber_A, sizeof(*(jobnumber_A)), 0) < 0)
        {
            ERR_MSG("recv");
            return 0;
        }
        printf("历史记录表成功发送\n");
    }
}
int root_chaxun_user(ser_cli *my_ser_cli_H)
{
    if (my_ser_cli_H->staff_information.key == 1)
        printf("root进入查询界面%d\n", __LINE__);
    else
        printf("用户进入查询界面%d\n", __LINE__);
    ser_cli my_ser_cli = *my_ser_cli_H;
    char **pres = NULL;
    int row, column;
    char *errmsg = NULL;
    int jobnumber, pass_w;
    char sql[528] = "";
    // printf("SELETC=%d line:%d\n", my_ser_cli.CLI_SELECT, __LINE__);
    switch (my_ser_cli.CLI_SELECT)
    {
    case 1:
        // 进入按员工号查找
        sprintf(sql, "select * from staff where jobnumber=%d;", my_ser_cli.staff_information.jobnumber);
        if (sqlite3_get_table(my_ser_cli.db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
            return 0;
        }
        if (row == 0) // 表示没有找到,向服务器发送信息
        {
            printf("debuf%d\n", __LINE__);
            my_ser_cli.CLI_SELECT = 2; // 0是修改,2是不存在
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        else
        {
            // 走到这里表示工号存在,将员工信息填充发送带客户端
            // 发送

            int index = 10;

            my_ser_cli.staff_information.key = atoi(pres[index++]);
            strcpy(my_ser_cli.staff_information.name, pres[index++]);
            my_ser_cli.staff_information.jobnumber = atoi(pres[index++]);
            my_ser_cli.staff_information.age = atoi(pres[index++]);
            my_ser_cli.staff_information.wage = atof(pres[index++]);
            strcpy(my_ser_cli.staff_information.post, pres[index++]);
            my_ser_cli.staff_information.phone = atoi(pres[index++]);
            strcpy(my_ser_cli.staff_information.time, pres[index++]);
            my_ser_cli.staff_information.state = atoi(pres[index++]);
            my_ser_cli.staff_information.pass_w = atoi(pres[index++]);

            my_ser_cli.CLI_SELECT = 0; // 0是查询成功
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        break;
    case 2:
        printf("进入按手机号查询");
        sprintf(sql, "select * from staff where phone=%d;", my_ser_cli.staff_information.phone);
        if (sqlite3_get_table(my_ser_cli.db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
            return 0;
        }
        if (row == 0) // 表示没有找到,向服务器发送信息
        {
            my_ser_cli.CLI_SELECT = 2; // 0是修改,2是不存在
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        else
        {
            // 进入这表示手机存在,填充信息
            int index = 10;

            my_ser_cli.staff_information.key = atoi(pres[index++]);
            strcpy(my_ser_cli.staff_information.name, pres[index++]);
            my_ser_cli.staff_information.jobnumber = atoi(pres[index++]);
            my_ser_cli.staff_information.age = atoi(pres[index++]);
            my_ser_cli.staff_information.wage = atof(pres[index++]);
            strcpy(my_ser_cli.staff_information.post, pres[index++]);
            my_ser_cli.staff_information.phone = atoi(pres[index++]);
            strcpy(my_ser_cli.staff_information.time, pres[index++]);
            my_ser_cli.staff_information.state = atoi(pres[index++]);
            my_ser_cli.staff_information.pass_w = atoi(pres[index++]);

            my_ser_cli.CLI_SELECT = 0; // 0是查询成功
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        break;
    default:
        printf("未定义指令码%d %d\n", my_ser_cli.CLI_SELECT, __LINE__);
        return 0;
        break;
    }
}
int root_xiugai_ser(ser_cli *my_ser_cli_H)
{

    printf("进入修改界面%d\n", __LINE__);
    ser_cli my_ser_cli = *my_ser_cli_H;
    char **pres = NULL;
    int row, column;
    char *errmsg = NULL;
    int jobnumber, pass_w;
    char sql[528] = "";
    char buf[128] = ""; // 辨别是员工号还是手机号
    int key = -1;       // 判断是否修改成功,跳出Switch时,值不为0,则修改成功
    // 判断是根据<1>员工号还是<2>手机号码查找
    switch (my_ser_cli.CLI_SELECT)
    {
    case 1:

        sprintf(sql, "select * from staff where jobnumber=%d;", my_ser_cli.staff_information.jobnumber);
        if (sqlite3_get_table(my_ser_cli.db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("debuf%d\n", __LINE__);
            printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
            return 0;
        }
        if (row == 0) // 表示没有找到,向服务器发送信息
        {
            printf("debuf%d\n", __LINE__);
            my_ser_cli.CLI_SELECT = 2; // 0是修改,2是不存在
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        else // 走到这里,表示根据员工号找到对应的员工信息
        {
            key = 1;

            // 根据flag判断修改什么
            switch (my_ser_cli.flag)
            {
            case 1:

                sprintf(sql, "update staff set name='%s' where jobnumber=%d;", my_ser_cli.staff_information.name, my_ser_cli.staff_information.jobnumber);

                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            case 2:
                sprintf(sql, "update staff set age=%d where jobnumber=%d;", my_ser_cli.staff_information.age, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);

                    key = 0;
                }
                break;
            case 3:
                sprintf(sql, "update staff set wage=%f where jobnumber=%d;", my_ser_cli.staff_information.wage, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);

                    key = 0;
                }
                break;
            case 4:
                sprintf(sql, "update staff set post='%s' where jobnumber=%d;", my_ser_cli.staff_information.post, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);

                    key = 0;
                }
                break;
            case 5:
                printf("update staff set phone=%d where jobnumber=%d;", my_ser_cli.staff_information.phone, my_ser_cli.staff_information.jobnumber);
                sprintf(sql, "update staff set phone=%d where jobnumber=%d;", my_ser_cli.staff_information.phone, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);

                    key = 0;
                }
                break;
            case 6:
                sprintf(sql, "update staff set time='%s' where jobnumber=%d;", my_ser_cli.staff_information.time, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);

                    key = 0;
                }
                break;
            case 7:
                printf("1111111\n");
                printf("update staff set pass_w=%d where jobnumber=%d\n;", my_ser_cli.staff_information.pass_w, my_ser_cli.staff_information.jobnumber);
                sprintf(sql, "update staff set pass_w=%d where jobnumber=%d;", my_ser_cli.staff_information.pass_w, my_ser_cli.staff_information.jobnumber);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    key = 0;
                    printf("debuf%d\n", __LINE__);
                }
                break;
            }
            if (key) // 如果为假,表示失败,发送失败给客户端
            {
                my_ser_cli.CLI_SELECT = 0; // 0是修改,其他是失败
                if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
                {
                    ERR_MSG("recv");
                    return 0;
                }
                return 1;
            }
        }
        break;
    case 2:
        // 因为1个变量不能存放判断的手机号和要修改的手机号,因此将判断的手机放到key变量中
        sprintf(sql, "select * from staff where phone=%d;", my_ser_cli.staff_information.key);
        if (sqlite3_get_table(my_ser_cli.db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
        {
            printf("get_table_jobnumber error%s %d\n", errmsg, __LINE__);
            return 0;
        }
        if (row == 0) // 表示没有找到,向服务器发送信息
        {
            my_ser_cli.CLI_SELECT = 2; // 0是修改,2是不存在
            if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
            {
                ERR_MSG("recv");
                return 0;
            }
        }
        else // 走到这里,表示根据员工号找到对应的员工信息
        {

            key = 1;
            // 根据flag判断修改什么
            switch (my_ser_cli.flag)
            {
            case 1:

                sprintf(sql, "update staff set name='%s' where id=%d;", my_ser_cli.staff_information.name, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    key = 0;
                    printf("debuf%d\n", __LINE__);
                }
                break;
            case 2:
                sprintf(sql, "update staff set age=%d where phone=%d;", my_ser_cli.staff_information.age, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            case 3:
                sprintf(sql, "update staff set wage=%f where phone=%d;", my_ser_cli.staff_information.wage, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            case 4:
                sprintf(sql, "update staff set post='%s' where phone=%d;", my_ser_cli.staff_information.post, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                printf("手机号查找成功 %d\n", __LINE__);
                break;
            case 5:
                sprintf(sql, "update staff set phone=%d where phone=%d;", my_ser_cli.staff_information.phone, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            case 6:
                sprintf(sql, "update staff set time='%s' where phone=%d;", my_ser_cli.staff_information.time, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            case 7:
                sprintf(sql, "update staff set pass_w=%d where phone=%d;", my_ser_cli.staff_information.pass_w, my_ser_cli.staff_information.key);
                if (sqlite3_exec(my_ser_cli.db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                {
                    printf("debuf%d\n", __LINE__);
                    key = 0;
                }
                break;
            }
            if (key) // 如果为假,表示失败,发送失败给客户端
            {
                my_ser_cli.CLI_SELECT = 0; // 0是修改成功 1是修改失败
                if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
                {
                    ERR_MSG("recv");
                    return 0;
                }
                printf("root修改信息成功 %d\n", __LINE__);
                return 1;
            }
            break;
        }
    default:
        printf("未定义指令码%d %d\n", my_ser_cli.CLI_SELECT, __LINE__);
        return 0;
        break;
    }
    return 1;
}
int user_ui(ser_cli *my_ser_cli)
{
    char sql[528] = "";
    ser_cli my_ser_cli_ui;
    ser_cli my_ser_cli_ui_1; // 除case1以外使用的
    my_ser_cli_ui_1.fd = my_ser_cli->fd;
    str_staff my_str_staff;
    // my_ser_cli_ui.staff_information = my_str_staff;
    my_ser_cli_ui.fd = my_ser_cli->fd;
    printf("用户%d进入用户界面\n", my_ser_cli->staff_information.jobnumber);
    char **pres = NULL;
    int row, column;
    char *errmsg;
    int jobnumber, pass_w;
    // 接收管理员操作指令码
    while (1)
    {
        my_ser_cli_ui.staff_information.jobnumber = 0;
        if (recv(my_ser_cli->fd, &my_ser_cli_ui, sizeof(my_ser_cli_ui), 0) < 0)
        {

            ERR_MSG("recv");
            return 0;
        }
        my_ser_cli_ui_1 = my_ser_cli_ui; // 备份,防止2345的操作影响到1
        my_ser_cli_ui_1.db = my_ser_cli->db;
        my_ser_cli_ui_1.fd = my_ser_cli->fd;
        switch (my_ser_cli_ui.CLI_SELECT_H)
        {
        case 1: // 查询个人信息
            root_chaxun_user(&my_ser_cli_ui_1);
            break;
        case 2: // 修改个人信息
            root_xiugai_ser(&my_ser_cli_ui_1);
            break;
        case 3: // 退出管理系统
            return 0;
            break;
        default:
            printf("输入错误,请重新输入\n");
            return 0;
            break;
        }
    }
}
int quit(ser_cli my_ser_cli)
{
    printf("客户端%d退出\n", my_ser_cli.fd);
    remove_epoll(epfd, my_ser_cli.fd);
    close(my_ser_cli.fd);
    return 0;
}
int add_fd(ser_cli *my_ser_cli_H)
{
    ser_cli my_ser_cli = *my_ser_cli_H;
    // 用户登录后添加账号信息到数组中,判断是否在线
    for (int i = 0; i < 10; i++)
    {
        if (my_ser_cli.staff_information.jobnumber == fd_A[i]) // 表示账号在线,不能重复登陆
        {
            printf("账号%d重复登陆 line:%d\n", my_ser_cli.staff_information.jobnumber, __LINE__);
            return 0;
        }
    }
    if (flag == 10) // 重置
        flag = 0;
    fd_A[flag++] = my_ser_cli.staff_information.jobnumber;
    return 1;
}
int remove_fd(ser_cli *my_ser_cli_H)
{
    ser_cli my_ser_cli = *my_ser_cli_H;
    for (int i = 0; i < 10; i++)
    {
        if (my_ser_cli.staff_information.jobnumber == fd_A[i]) // 找到下线账号
        {
            fd_A[i] = 0; // 将账号信息删除
            flag--;
            printf("账号%d下线 line:%d\n", my_ser_cli.staff_information.jobnumber, __LINE__);
            return 0;
        }
    }
}

1.3服务器头文件

#ifndef __CLIENT_H__
#define __CLIENT_H__
/******头文件区域*******/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/epoll.h>
#include <sqlite3.h>
#include <pthread.h>
/******引用区域*******/
// 创建数据库并打开数据表
sqlite3 * Sqlite_Create(void);
// 服务器 套接字->端口重启->绑定->监听
int sock_listen(void);
// 红黑树监听事件信息的添加
int add_epoll(int epfd, int fd);
int remove_epoll(int epfd,int fd);
//添加线程管理交互界面
void *callBack(void *arg);

#define DEBUG_LINE printf("Debug line:%d\n",__LINE__)
// 错误码
#define ERR_MSG(msg)                           \
    do                                         \
    {                                          \
        fprintf(stderr, "line:%d ", __LINE__); \
        perror(msg);                           \
    } while (0)

#define PORT 6666            // 服务器端口
#define IP "192.168.250.100" // 服务器IP地址
#define MAX 10   //顺序表最大容量
// 信息结构体,因为使用IPv4,因此使用sockaddr_in填充bind的第二个参数
struct sockaddr_in my_ser; // 服务器信息结构体
struct sockaddr_in my_cin; // 保存客户端信息结构体
// 员工信息结构体
typedef struct staff
{
    int key;       // 判断是用户还是管理员 1是管理 2是用户
    char name[128];     // 员工姓名
    int jobnumber; // 员工工号
    int age;       // 员工年龄
    float wage;    // 当前的薪资
    char post[128];     // 岗位名称
    int phone;     // 手机号
    char time[128];     // 精确到日,入职时间
    int state;     // 是否在线 1表示在线
    int pass_w;    // 密码
} str_staff;
// 服务器与客户端通信的结构体
typedef struct info
{
    int fd;//客户端的描述符
    int CLI_SELECT;                // 登陆时选择的操作 1管理员登陆,2是用户登陆 3是退出
    int CLI_SELECT_H;  //登陆后选择的操作 1.添加员工信息 2.修改员工记录 3.查询员工记 4.查询历史 5,退出管理
    int events_i;       //保存红黑树数组的下标
    int cli_n_p; //高账号密码权力的匹配程度,1表示账号不存在2表示密码不正确3表示不是特权4表示不是用户5均成功
    int flag;//进入2级界面选项后,传递的自定义标志位
    sqlite3 *db;  
    str_staff staff_information; // 员工信息结构体
} ser_cli;
//客户端发送信息
int ser_cli_tongxing(ser_cli * my_str_staff,int sock_fd);
int root_ui(ser_cli *my_str_staff);
int user_ui(ser_cli *my_ser_staff);
//添加员工信息
ser_cli *add_root_and_user(ser_cli *my_ser_cli_ui);
//修改员工信息
int root_xiugai_ser(ser_cli *my_ser_cli_ui_1);
//root查询到员工信息
int root_chaxun_user(ser_cli *my_str_staff); 
//添加员工信息到数组中
int add_jobnumber_A(ser_cli *my_ser_cli_H);
//root查询历史信息
int root_lishi_user(ser_cli *my_ser_cli_H);
//判断账号是否重复登陆
int add_fd(ser_cli *my_ser_cli_H);
int remove_fd(ser_cli *my_ser_cli_H);
//退出函数
int quit(ser_cli my_ser_cli);
typedef struct newfd
{
    int fd;
}my_fd;
typedef struct fd_1
{
    my_fd arr[MAX];
    int len;
}str_newfd;
// 保存就绪事件的信息,用于移植到红黑树中
struct epoll_event event;
// 存放就绪事件描述符的数组
sqlite3 * debuf_db;
struct epoll_event events[10];
pthread_t tid;
int fd_A[10];
ser_cli jobnumber_A[10];
int epfd ;//红黑树根节点
#endif

2.客户端代码

2.1客户端函数入口

#include "client.h"
int main(int argc, char const *argv[])
{
    // 创建套接字
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if (cfd < 0)
    {
        ERR_MSG("socket");
        goto OUT1;
    }
    // 连接服务器
    // 1.填充服务器的信息
    my_ser.sin_family = AF_INET;
    my_ser.sin_port = htons(PORT);
    my_ser.sin_addr.s_addr = inet_addr(IP);
    // 连接
    if (connect(cfd, (struct sockaddr *)&my_ser, sizeof(my_ser)) < 0)
    {
        ERR_MSG("connet");
        goto OUT2;
    }
    printf("connect server success cfd=%d %d\n",cfd,__LINE__);
    // 用户的选择
    int key = -1;
    ser_cli my_ser_cli; //通信结构体
    str_staff my_str_staff; //员工信息
    while (1)
    {
        printf("<*************************> 1\n");
        printf("<********1.管理员登陆******> 1\n");
        printf("<********2.用户登陆*******> 1\n");
        printf("<********3.退出***********> 1\n");
        printf("<************************> 1\n");
        printf("\n请选择你要进行的操作:");

        scanf("%d", &key);
        switch (key)
        {
        case 1:
            // 改变对应的结构体信息
            my_ser_cli.CLI_SELECT = 1;
            my_ser_cli.staff_information = my_str_staff;
            my_ser_cli.fd=cfd;
            my_ser_cli.staff_information.key=1;
            if(ser_cli_tongxing(&my_ser_cli,cfd)==1)
            {
                //返回值为1表示管理员验证成功
                //进入管理员控制界面
                my_ser_cli.fd=cfd;
                root_ui(&my_ser_cli);
            }
            break;
        case 2:
            // 改变对应的结构体信息
            my_ser_cli.CLI_SELECT = 2;
            my_ser_cli.staff_information = my_str_staff;
            my_ser_cli.staff_information.key=2;
            my_ser_cli.fd=cfd;
            if(ser_cli_tongxing(&my_ser_cli,cfd)==1)
            {
                //表示用户登陆成功,进入用户控制界面
                user_ui(&my_ser_cli);
            }
            break;
        case 3:
            // 改变对应的结构体信息
            my_ser_cli.CLI_SELECT = 3;
            if (send(cfd,&my_ser_cli, sizeof(my_str_staff), 0) < 0)
            {
                ERR_MSG("send");
            }
            close(cfd);
            printf("退出成功\n");
            exit(1);
            break;
        default:
            printf("输入错误,请重新输入:\n");
            break;
        }
    }
    // 关闭套接字
    close(cfd);
    return 0;
OUT2:
    close(cfd);
OUT1:
    return cfd;
    return 0;
}

2.2客户端执行代码

#include "client.h"

int ser_cli_tongxing(ser_cli *my_str_staff, int sock_fd)
{

    ser_cli my_str_staff_1;
    my_str_staff_1.CLI_SELECT = my_str_staff->CLI_SELECT;
    my_str_staff_1.staff_information = my_str_staff->staff_information;
    int jobnumber = 0;
    int pass_w = 0;
OUT1:
    printf("输入你的工号:");
    scanf("%d", &jobnumber);
    user_jobnumber=jobnumber;
    if (jobnumber == 0)
    {
        printf("输入失败,请重新输入%d\n", __LINE__);
        goto OUT1;
    }
    while (getchar() != 10)
        ;
    my_str_staff_1.staff_information.jobnumber = jobnumber;
OUT2:
    printf("输入你的密码:");
    scanf("%d", &pass_w);
    if (jobnumber == 0)
    {
        printf("输入失败,请重新输入%d\n", __LINE__);
        goto OUT2;
    }
    while (getchar() != 10)
        ;
    my_str_staff_1.staff_information.pass_w = pass_w;
    // printf("jobnumber=%d\n",my_str_staff_1.staff_information.jobnumber);
    // 账号密码输入完毕,请求服务器登陆
    // printf("pass_w=%d\n",my_str_staff_1.staff_information.pass_w);
    send(sock_fd, &my_str_staff_1, sizeof(my_str_staff_1), 0);
    // 接收信息
    if (recv(sock_fd, &my_str_staff_1, sizeof(my_str_staff_1), 0) < 0)
    {
        ERR_MSG("recv");
        return 0;
    }
    printf("my_str_staff_1.cli_n_p==%d\n", my_str_staff_1.cli_n_p);
    // 根据接收到的信息判断
    if (my_str_staff_1.cli_n_p == 1)
    {
        printf("工号不正确,请重新输入\n");
        return 0;
    }
    else if (my_str_staff_1.cli_n_p == 2)
    {
        printf("密码不正确,请重新输入\n");
        return 0;
    }
    else if (my_str_staff_1.cli_n_p == 3)
    {
        printf("请从管理员模式登陆\n");
        return 0;
    }
    else if (my_str_staff_1.cli_n_p == 4)
    {
        printf("员工不得访问root权限\n");
        return 0;
    }
    else if (my_str_staff_1.cli_n_p == 5)
    {
        if(my_str_staff_1.flag==0)//表示账号重复登陆了
        {
            printf("你的账号正在登陆中\n");
            exit(1);
        }
        printf("登陆成功 %d\n",__LINE__);
        return 1;
    }
    printf("接收错误\n");
    return 0;
}

// 管理员控制界面
int root_ui(ser_cli *my_str_staff)
{
    int key = -1;
    while (1)
    {
        printf("<****************************> 1\n");
        printf("<*********管理操作系统********> 1\n");
        printf("<********1.添加员工信息*******> 1\n");
        printf("<********2.修改员工信息*******> 1\n"); // 两种方式 工号 手机号
        printf("<********3.查询员工信息*******> 1\n"); // 两种方式 工号 手机号
        printf("<********4.查询历史记录*******> 1\n");
        printf("<********5.退出管理系统*******> 1\n");
        printf("<****************************> 1\n");
        printf("\n请选择你要进行的操作:");
        scanf("%d", &key);
        switch (key)
        {
        case 1:
            add_root_and_user(my_str_staff);
            break;
        case 2:
            root_xiugai_user(my_str_staff); // 修改员工信息
            break;
        case 3:
            chaxun_user(my_str_staff); //root界面和用户界面均能掉
            break;
        case 4:
            root_chaxun_lishi(my_str_staff);
            break;
        case 5:
            my_str_staff->CLI_SELECT_H = 5;
            if (send(my_str_staff->fd, my_str_staff, sizeof(*(my_str_staff)), 0) < 0)
            {
                ERR_MSG("send");
                return 0;
            }
            printf("管理系统退出成功\n");
            close(my_str_staff->fd);
            exit(1);
            break;
        default:
            printf("输入错误,请重新输入\n");
            break;
        }
    }
}
// 进入用户控制界面
int user_ui(ser_cli *my_str_staff)
{
    int key = -1;

    while (1)
    {

        printf("<****************************> 1\n");
        printf("<*********员工操作系统********> 1\n");
        printf("<********1.查询个人信息*******> 1\n");
        printf("<********2.修改个人信息*******> 1\n");
        printf("<********3.退出管理系统*******> 1\n");
        printf("<****************************> 1\n");
        printf("\n请选择你要进行的操作:");
        scanf("%d", &key);
        switch (key)
        {
        case 1:
            user_chaxun(my_str_staff);
            break;
        case 2:
            user_xiugai(my_str_staff);
            break;
        case 3:
            printf("退出成功\n");
            exit(1);
            break;
        default:
            printf("输入错误,请重新输入%d\n", __LINE__);
            break;
        }
    }
}
//员工查询个人信息
int user_chaxun(ser_cli *my_ser_cli_H)
{
    printf("员工进入查询界面 line:%d\n",__LINE__);
    ser_cli my_ser_cli = *my_ser_cli_H;
    my_ser_cli.fd = my_ser_cli_H->fd;
    int key = -1;
    while (1)
    {
        printf("查询方式 1<工号> 2.退出查询\n");
        printf("请输入>>>>");
        scanf("%d", &key);
        switch (key)
        {
        case 1:
            my_ser_cli.CLI_SELECT = 1;//高速服务器按照工号查询
            my_ser_cli.CLI_SELECT_H=1;//二级界面选项,
            my_ser_cli.staff_information.jobnumber=user_jobnumber;
            /*输出查询信息*/
            root_chaxun_user(&my_ser_cli);
            break;
        case 2:
            printf("用户退出成功\n");
            return 0;
            break;
        default:
            printf("输入错误,重新输入%d\n", __LINE__);
            break;
        }
    }
    
}
//员工修改个人密码
int user_xiugai(ser_cli *my_ser_cli_H)
{
    ser_cli my_ser_cli=*my_ser_cli_H;
    printf("1<修改密码> 2<退出界面>\n");
    int key=-1;
    my_ser_cli.CLI_SELECT=1;//告诉服务按照员工号查询后修改
    my_ser_cli.CLI_SELECT_H=2;//引导服务器二级界面的选择
    my_ser_cli.flag=7;//引导服务器修改密码
    my_ser_cli.staff_information.jobnumber=user_jobnumber;
    int buf;
    printf("请输入>>>>");
    scanf("%d",&key);
    
    switch(key)
    {
        case 1:
            printf("修改后的密码>>:");
            scanf("%d",&buf);
            my_ser_cli.staff_information.pass_w=buf;
            xiugai_user_to_ser(&my_ser_cli,7);
            break;
        case 2:
            printf("用户退出成功\n");
            return 0;
            break;
    }
}
//root查询所有历史
int root_chaxun_lishi(ser_cli *my_ser_cli_H)
{
    // 重新保存
    printf("最多查询当前10位\n");
    ser_cli my_ser_cli = *my_ser_cli_H;
    ser_cli my_ser_cli_A[10];
    my_ser_cli.CLI_SELECT_H = 4; // 提示服务器进入哪一步
    if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("send");
        return 0;
    }
    //接收历史查询信息
    printf("size=%ld\n",sizeof(*(my_ser_cli_A)));
    if(recv(my_ser_cli_H->fd,my_ser_cli_A,sizeof(*(my_ser_cli_A)),0)<0)
    {
        ERR_MSG("send");
        return 0;
    }
    for(int i=0;i<my_ser_cli_A->flag+1;i++)
    {
        printf("1.<<<<工号:%d的信息>>>>>\n",my_ser_cli_A[i].staff_information.jobnumber);
        printf("id        = %d\n", my_ser_cli_A[i].staff_information.key);
        printf("name      = %s\n",my_ser_cli_A[i].staff_information.name);
        printf("jobnumber = %d\n", my_ser_cli_A[i].staff_information.jobnumber);
        printf("age       = %d\n", my_ser_cli_A[i].staff_information.age);
        printf("wage      = %2.f\n", my_ser_cli_A[i].staff_information.wage);
        printf("phone     = %d\n", my_ser_cli_A[i].staff_information.phone);
        printf("time      = %s\n", my_ser_cli_A[i].staff_information.time);
        printf("state     = %d\n", my_ser_cli_A[i].staff_information.state);
        printf("pass_w    = %d\n", my_ser_cli_A[i].staff_information.pass_w);
        printf("\n");
    }
    printf("查询成功 是否退出(Y/N)\n");
    char key;
    while(getchar()!=10);
    scanf("%c",&key);
    while(getchar()!=10);
    if(key=='y'||key=='Y')
    return 0;
    else
    {
        sleep(10);
    }
}
// 添加员工
ser_cli *add_root_and_user(ser_cli *my_ser_cli_ui)
{
    ser_cli my_ser_cli;
    my_ser_cli.fd = my_ser_cli_ui->fd;
    printf("是否为管理1<是> 2<不是>:");
    int key = -1;
    scanf("%d", &key);
    my_ser_cli.staff_information.key = key;
    while (getchar() != 10)
        ;
    printf("key=%d\n", my_ser_cli.staff_information.key);

    printf("输入员工姓名:");
    char name[128] = "";
    scanf("%s", name);
    printf("name=%s", name);
    strcpy(my_ser_cli.staff_information.name, name);
    while (getchar() != 10)
        ;
    printf("name=%s\n", my_ser_cli.staff_information.name);

    printf("输入员工工号:");
    key = -1;
    scanf("%d", &key);
    if (key == 0)
    {
        printf("工号不可为0\n");
    }
    my_ser_cli.staff_information.jobnumber = key;
    while (getchar() != 10)
        ;
    printf("jobnumber=%d\n", my_ser_cli.staff_information.jobnumber);

    printf("输入员工年龄:");
    key = -1;
    scanf("%d", &key);
    my_ser_cli.staff_information.age = key;
    while (getchar() != 10)
        ;

    printf("age=%d\n", my_ser_cli.staff_information.age);

    printf("输入员工薪资:");
    float wage = -1;
    scanf("%f", &wage);
    my_ser_cli.staff_information.wage = key;
    while (getchar() != 10)
        ;
    printf("wage=%f\n", my_ser_cli.staff_information.wage);

    printf("输入员工岗位:");
    char post[128] = "";
    scanf("%s", post);
    strcpy(my_ser_cli.staff_information.post, post);
    while (getchar() != 10)
        ;
    printf("post=%s\n", my_ser_cli.staff_information.post);

    printf("输入员工手机:");
    key = -1;
    scanf("%d", &key);
    my_ser_cli.staff_information.phone = key;
    while (getchar() != 10)
        ;
    printf("key=%d\n", my_ser_cli.staff_information.phone);

    printf("输入员工入职时间:");
    scanf("%s", post);
    strcpy(my_ser_cli.staff_information.time, post);
    printf("time=%s\n", my_ser_cli.staff_information.time);

    printf("输入员工密码:");
    key = -1;
    scanf("%d", &key);
    my_ser_cli.staff_information.pass_w = key;
    while (getchar() != 10)
        ;
    printf("pass_w=%d\n", my_ser_cli.staff_information.pass_w);
    my_ser_cli.staff_information.state = 0;
    my_ser_cli.CLI_SELECT_H = 1; // 添加员工信息指令码
    printf("state=%d\n", my_ser_cli.staff_information.state);
    printf("send fd =%d %d\n", my_ser_cli_ui->fd, __LINE__);
    if (send(my_ser_cli_ui->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("send");
        return 0;
    }
    // 接收消息是否添加成功
    my_ser_cli.CLI_SELECT = 0;
    if (recv(my_ser_cli_ui->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("recv");
        return 0;
    }
    // 服务器发来标志位,判断账号是否存在为1
    if (my_ser_cli.CLI_SELECT == 1)
    {
        printf("该工号已经存在 %d\n", __LINE__);
        return 0;
    }
    if (my_ser_cli.staff_information.jobnumber)
    {
        printf("员工添加信息成功 %d\n", __LINE__);
    }
}
// root修改员工信息,将修改的数据发送到服务器
int xiugai_user_to_ser(ser_cli *my_str_staff, int key)
{
    // 重新保存
    ser_cli my_ser_cli = *my_str_staff;
    my_ser_cli.CLI_SELECT_H = 2; // 提示服务器进入哪一步
    printf("key=%d\n", key);
   
    printf("pass_w=%d %d\n",my_ser_cli.staff_information.pass_w,__LINE__);
    if (send(my_str_staff->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("send");
        return 0;
    }
    // 接收消息是否修改成功,先改变为失败标志
    my_ser_cli.CLI_SELECT = 1;
    if (recv(my_str_staff->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("recv");
        return 0;
    }
    // 服务器发来标志,如果成功则将SELECT修改为0,否则提示其搜索失败
    if (my_ser_cli.CLI_SELECT != 0)
    {
        if (my_str_staff->CLI_SELECT == 1)
        {
            printf("按员工账号搜索失败\n");
        }
        if (my_str_staff->CLI_SELECT == 2)
        {
            printf("按手机号码搜索失败\n");
        }
        return 0;
    }
    else
    {
        printf("员工信息修改成功\n");
    }
    // 走到这里表示修改成功
    return 1;
}
// root修改员工信息
ser_cli *root_xiugai_user(ser_cli *my_str_staff)
{
    ser_cli my_ser_cli;
    my_ser_cli.fd = my_str_staff->fd;
    int key = -1;
    int key_flag;
    printf("只能修改用户信息\n");
    while (1)
    {
        key = -1;
        printf("1:按照员号修改 2:按照手机号码修改 3:退出\n");
        printf("*请输入你的查找方式*:");
        scanf("%d", &key);
        my_ser_cli.CLI_SELECT = key; // 1按照员工号 2按照手机号
        while (getchar() != 10)
            ;
        switch (key)
        {
        case 1:
            printf("输入员工工号:");
            key = -1;
            scanf("%d", &key);
            if (key == 0)
            {
                printf("工号不可为0\n");
            }
            my_ser_cli.staff_information.jobnumber = key;
            while (getchar() != 10)
                ;

            printf("1<姓名> 2<年龄> 3<薪水>n 4<岗位>  ");
            printf("5<手机号>  6<入职时间>   7<密码>\n");
            key = -1;
            printf("*请输入你想修改的信息*:");
            scanf("%d", &key);
            key_flag=key;
            my_ser_cli.flag=key_flag;
            switch (key)
            {
            case 1:
                printf("输入员工姓名:");
                char name[128] = "";
                scanf("%s", name);
                printf("name=%s", name);
                strcpy(my_ser_cli.staff_information.name, name);
                while (getchar() != 10)
                    ;
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 2:
                printf("输入员工年龄:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.age = key;
                while (getchar() != 10)
                    ;

                printf("age=%d\n", my_ser_cli.staff_information.age);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 3:
                printf("输入员工薪资:");
                float wage = -1;
                scanf("%f", &wage);
                my_ser_cli.staff_information.wage = key;
                while (getchar() != 10)
                    ;
                printf("wage=%f\n", my_ser_cli.staff_information.wage);
                // 为服务器提供是修改哪一项
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 4:
                printf("输入员工岗位:");
                char post[128] = "";
                scanf("%s", post);
                strcpy(my_ser_cli.staff_information.post, post);
                while (getchar() != 10)
                    ;
                printf("post=%s\n", my_ser_cli.staff_information.post);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 5:
                printf("输入员工手机:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.phone = key;
                while (getchar() != 10)
                    ;
                printf("key=%d\n", my_ser_cli.staff_information.phone);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 6:
                printf("输入员工入职时间:");
                scanf("%s", post);
                strcpy(my_ser_cli.staff_information.time, post);
                printf("time=%s\n", my_ser_cli.staff_information.time);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 7:
                printf("输入员工密码:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.pass_w = key;
                while (getchar() != 10)
                    ;
                printf("pass_w=%d\n", my_ser_cli.staff_information.pass_w);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            default:
                printf("输入错误,重新输入\n");
                break;
            }
            break;
        case 2:
            my_ser_cli.CLI_SELECT = 2;
            printf("输入员工手机:");
            key = -1;
            scanf("%d", &key);
            my_ser_cli.staff_information.key = key; // 手机号用key暂时保存
            while (getchar() != 10)
                ;
            printf("key=%d\n", my_ser_cli.staff_information.key);

            printf("1<姓名> 2<年龄> 3<薪水>n 4<岗位>  ");
            printf("5<手机号>  6<入职时间>   7<密码>\n");
            printf("*请输入你想修改的信息*:");
            key = -1;
            scanf("%d", &key);
            key_flag=key;
            my_ser_cli.flag=key_flag;
            switch (key)
            {
            case 1:
                printf("输入员工姓名:");
                char name[128] = "";
                scanf("%s", name);
                printf("name=%s", name);
                strcpy(my_ser_cli.staff_information.name, name);
                while (getchar() != 10)
                    ;
                printf("name=%s\n", my_ser_cli.staff_information.name);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 2:
                printf("输入员工年龄:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.age = key;
                while (getchar() != 10)
                    ;

                printf("age=%d\n", my_ser_cli.staff_information.age);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;

            case 3:
                printf("输入员工薪资:");
                float wage = -1;
                scanf("%f", &wage);
                my_ser_cli.staff_information.wage = wage;
                while (getchar() != 10)
                    ;
                printf("wage=%f\n", my_ser_cli.staff_information.wage);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }

                break;
            case 4:
                printf("输入员工岗位:");
                char post[128] = "";
                scanf("%s", post);
                strcpy(my_ser_cli.staff_information.post, post);
                while (getchar() != 10)
                    ;
                printf("post=%s\n", my_ser_cli.staff_information.post);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 5:
                printf("输入员工手机:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.phone = key;
                while (getchar() != 10)
                    ;
                printf("key=%d\n", my_ser_cli.staff_information.phone);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 6:
                printf("输入员工入职时间:");
                scanf("%s", post);
                strcpy(my_ser_cli.staff_information.time, post);
                printf("time=%s\n", my_ser_cli.staff_information.time);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            case 7:
                printf("输入员工密码:");
                key = -1;
                scanf("%d", &key);
                my_ser_cli.staff_information.pass_w = key;
                while (getchar() != 10)
                    ;
                printf("pass_w=%d\n", my_ser_cli.staff_information.pass_w);
                if (xiugai_user_to_ser(&my_ser_cli, key) < 0)
                {
                    return 0;
                }
                break;
            default:
                printf("输入错误,重新输入%d\n", __LINE__);
                break;
            }
            break;
        case 3:
            printf("key=%d 退出修改%d\n", key, __LINE__);
            return 0;
            break;
        default:
            printf("输入错误,重新输入%d\n", __LINE__);
            break;
        }
    }
}
// root查询员工的信息选择
int chaxun_user(ser_cli *my_ser_cli_H)
{
    ser_cli my_ser_cli = *my_ser_cli_H;
    my_ser_cli.fd = my_ser_cli_H->fd;
    printf("root进入员工查询\n");
    int key = -1;
    while (1)
    {
        printf("查询方式 1<工号> 2.手机号 3.退出查询\n");
        printf("请输入>>>>");
        scanf("%d", &key);
        switch (key)
        {
        case 1:
            my_ser_cli.CLI_SELECT = 1;
            printf("<<<按照工号查询>>>\n");
            key = -1;
            scanf("%d", &key);
            if (key == 0)
            {
                printf("工号不可为0\n");
            }
            my_ser_cli.staff_information.jobnumber = key;
            while (getchar() != 10)
                ;
            printf("jobnumber=%d\n", my_ser_cli.staff_information.jobnumber);
            /*输出查询信息*/
            if(root_chaxun_user(&my_ser_cli)<0)
            {
                break;
            }
            break;
        case 2:
            printf("<<<按照手机号查询>>>\n");
            my_ser_cli.CLI_SELECT = 2;
            printf("输入员工手机:");
            key = -1;
            scanf("%d", &key);
            my_ser_cli.staff_information.phone = key; // 手机号用key暂时保存
            while (getchar() != 10)
                ;
            printf("key=%d\n", my_ser_cli.staff_information.key);
            /*输出查询信息*/
            if(root_chaxun_user(&my_ser_cli)<0)
            {
                break;
            }
            break;
        case 3:
            printf("<<<退出成功>>>\n");
            return 0;
            break;
        default:
            printf("输入错误,重新输入%d\n", __LINE__);
            break;
        }
    }
}
//root查询的功能
int root_chaxun_user(ser_cli *my_ser_cli_H)
{
    //按照SELECT的值判断根据什么查找
    // 重新保存
    ser_cli my_ser_cli = *my_ser_cli_H;
    if(my_ser_cli.staff_information.key==1)//判断是用户还是root
    my_ser_cli.CLI_SELECT_H = 3; // 提示服务器进入哪一步
    else if(my_ser_cli.staff_information.key==2)//员工
    my_ser_cli.CLI_SELECT_H=1;
    if (send(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("send");
        return 0;
    }
    // 接收消息是否查询成功,先改变为失败标志
    my_ser_cli.CLI_SELECT = 1;
    if (recv(my_ser_cli_H->fd, &my_ser_cli, sizeof(my_ser_cli), 0) < 0)
    {
        ERR_MSG("recv");
        return 0;
    }
    // 服务器发来标志,如果成功则将SELECT修改为0,否则提示其搜索失败
    if (my_ser_cli.CLI_SELECT != 0)
    {
        if (my_ser_cli_H->CLI_SELECT == 1)
        {
            printf("按员工账号查找失败\n");
        }
        if (my_ser_cli_H->CLI_SELECT == 2)
        {
            printf("按手机号码查找失败\n");
        }
        return 0;
    }
    if(my_ser_cli.CLI_SELECT==0)
    {
        //先打印查询成功的信息
        printf("id        = %d\n", my_ser_cli.staff_information.key);
        printf("name      = %s\n",my_ser_cli.staff_information.name);
        printf("jobnumber = %d\n", my_ser_cli.staff_information.jobnumber);
        printf("age       = %d\n", my_ser_cli.staff_information.age);
        printf("wage      = %2.f\n", my_ser_cli.staff_information.wage);
        printf("phone     = %d\n", my_ser_cli.staff_information.phone);
        printf("time      = %s\n", my_ser_cli.staff_information.time);
        printf("state     = %d\n", my_ser_cli.staff_information.state);
        printf("pass_w    = %d\n", my_ser_cli.staff_information.pass_w);
        printf("<<<<<<员工信息查找成功>>>>>\n");
    }
    // 走到这里表示修改成功
    return 1;
}

2.3客户端头文件

#ifndef __CLIENT_H__
#define __CLIENT_H__
/******头文件区域*******/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/epoll.h>
#include <sqlite3.h>
#include <pthread.h>
/******引用区域*******/
// 创建数据库并打开数据表
sqlite3 * Sqlite_Create(void);
// 服务器 套接字->端口重启->绑定->监听
int sock_listen(void);
// 红黑树监听事件信息的添加
int add_epoll(int epfd, int fd);
//添加线程管理交互界面
void *callBack(void *arg);

#define DEBUG_LINE printf("Debug line:%d\n",__LINE__)
// 错误码
#define ERR_MSG(msg)                           \
    do                                         \
    {                                          \
        fprintf(stderr, "line:%d ", __LINE__); \
        perror(msg);                           \
    } while (0)

#define PORT 6666            // 服务器端口
#define IP "192.168.250.100" // 服务器IP地址
#define MAX 10   //顺序表最大容量
// 信息结构体,因为使用IPv4,因此使用sockaddr_in填充bind的第二个参数
struct sockaddr_in my_ser; // 服务器信息结构体
struct sockaddr_in my_cin; // 保存客户端信息结构体
// 员工信息结构体
typedef struct staff
{
    int key;       // 判断是用户还是管理员 1是管理 2是用户
    char name[128];     // 员工姓名
    int jobnumber; // 员工工号
    int age;       // 员工年龄
    float wage;    // 当前的薪资
    char post[128];     // 岗位名称
    int phone;     // 手机号
    char time[128];     // 精确到日,入职时间
    int state;     // 是否在线 1表示在线
    int pass_w;    // 密码
} str_staff;
// 服务器与客户端通信的结构体
typedef struct info
{
    int fd;//客户端的描述符
    int CLI_SELECT;                // 登陆时选择的操作 1管理员登陆,2是用户登陆 3是退出
    int CLI_SELECT_H;  //登陆后选择的操作 1.查询信息 2.修改密码 3.查询记录
    int events_i;       //保存红黑树数组的下标
    int cli_n_p; //高账号密码权力的匹配程度,1表示账号不存在2表示密码不正确3表示不是特权4表示不是用户5均成功
    int flag;//进入2级界面选项后,传递的自定义标志位
    sqlite3 *db; 
    str_staff staff_information; // 员工信息结构体
} ser_cli;
//客户端发送信息
int ser_cli_tongxing(ser_cli * my_str_staff,int sock_fd);
int root_ui(ser_cli *my_str_staff);
int user_ui(ser_cli *my_ser_staff);
//添加员工信息
ser_cli *add_root_and_user(ser_cli *my_ser_cli_ui);
//修改员工信息
ser_cli *root_xiugai_user(ser_cli *my_str_staff);
//修改员工信息后与服务器通信
int xiugai_user_to_ser(ser_cli *my_str_staff,int key);
//root查询员工信息
int chaxun_user(ser_cli * my_str_staff);
int root_chaxun_user(ser_cli *my_str_staff); //输出查询到的结果
//root查询历史表
int root_chaxun_lishi(ser_cli *my_ser_cli_H);
//用户查询个人信息
int user_chaxun(ser_cli *my_ser_cli_H);
//用户修改个人密码
int user_xiugai(ser_cli *my_ser_cli_H);
typedef struct newfd
{
    int fd;
}my_fd;
typedef struct fd_1
{
    my_fd arr[MAX];
    int len;
}str_newfd;
// 保存就绪事件的信息,用于移植到红黑树中
struct epoll_event event;
// 存放就绪事件描述符的数组
struct epoll_event events[10];
int user_jobnumber;//保存客户顿的user工号
#endif

3.Makefile

CC = gcc
CFLAGS = -Wextra
LDFLAGS = -lsqlite3 -pthread
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = program

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(OBJ)
	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(OBJ) $(TARGET)

文章来源地址https://www.toymoban.com/news/detail-621703.html

到了这里,关于基于数据库 Sqlite3 的 root 管理系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • sqlite3数据库的实现

    sqlite3代码实现数据库的插入、删除、修改、退出功能

    2024年02月12日
    浏览(15)
  • SQlite3数据库相关相关命令

    SQlite3数据库相关相关命令

    1. 创建表格 2. 插入数据 3. 查看数据库记录 4. 删除信息 5. 更新数据 6. 增加一列 7. 删除一列 (sqlite3 不支持直接删除一列) 1. 打开数据库 2. 关闭数据库 3. 错误信息 4. 执行一条sql语句 5. 查询回调函数 6. 查询函数 小知识:如果结构体中定义的是一级指针,那么你要定义变量取

    2024年02月16日
    浏览(14)
  • sqlite3将词典导入数据库

    使用sqlite3代码实现将词典导入数据库中

    2024年02月12日
    浏览(13)
  • 02.sqlite3学习——嵌入式数据库的基本要求和SQLite3的安装

    02.sqlite3学习——嵌入式数据库的基本要求和SQLite3的安装

    目录 嵌入式数据库的基本要求和SQLite3的安装 嵌入式数据库的基本要求 常见嵌入式数据库 sqlite3简介 SQLite3编程接口模型 ubuntu 22.04下的SQLite安装 (1)安装SQLite3软件 sudo apt-get install sqlite3 (2)安装库文件 sudo apt-get install libsqlite3-dev 安装成功后输入sqlite3查看 (3)安装sqlite3可

    2024年02月11日
    浏览(19)
  • 嵌入式数据库之sqlite3

    嵌入式数据库之sqlite3

            数据:能够输入计算机并能被计算机程序识别和处理的信息集合。         数据库:数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。 1.大型数据库         Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作

    2024年02月10日
    浏览(12)
  • 【嵌入式数据库之sqlite3】

    目录 一.数据库基本概念(理解) 1.数据 2.数据库 二.常用的数据的数据库(了解) 1.大型数据库 2.中型数据库 3.小型数据库 三.基于嵌入式的数据库(了解) 四.SQLite基础(了解) 五.创建数据库(熟练) 1.手工创建 2.代码创建 六.SQLite编程接口 七.代码示例(学生管理系统) 八

    2024年02月09日
    浏览(11)
  • SQLite3数据库的介绍和使用(面向业务编程-数据库)

    SQLite是一种用C语言实现的的SQL数据库 它的特点有:轻量级、快速、独立、高可靠性、跨平台 它广泛应用在全世界范围内的手机电脑应用的内建数据库 官网地址:https://www.sqlite.org/index.html SQLite因为其采用文件存储,且容易移植。在嵌入式中应用非常广泛,可以说是嵌入式业

    2024年02月02日
    浏览(16)
  • 【C++】开源:sqlite3数据库配置使用

    【C++】开源:sqlite3数据库配置使用

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍sqlite3数据库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 项目Github地址: https://github.com/sqlite/sqlite SQLite 是一种嵌入式

    2024年02月14日
    浏览(8)
  • 用于将Grafana默认数据库sqlite3迁移到MySQL数据库

    用于将Grafana默认数据库sqlite3迁移到MySQL数据库

    以下是一个方案,用于将Grafana数据迁移到MySQL数据库。 背景: grafana 默认采用的是sqlite3,当我们要以集群形式部署的时使用mysql较为方便,试了很多sqlite转mysql的方法要么收费,最后放弃。选择自己动手风衣足食。 目标: 迁移sqlite3切换数据库到mysql 前提条件: 确保你已经安装了

    2024年02月20日
    浏览(13)
  • 10.1 嵌入式数据库之sqlite3

    【1】数据库    1, 数据库的安装        sudo dpkg -i  *.deb    2, 数据库命令:       1)系统命令 , 都以\\\'.\\\'开头          .exit           .quit          .table   查看表          .schema  查看表的结构                  2)sql语句, 都以‘;’结尾         1-- 创建一张表

    2024年02月12日
    浏览(15)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包