国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于數(shù)據(jù)庫 Sqlite3 的 root 管理系統(tǒng)

這篇具有很好參考價值的文章主要介紹了基于數(shù)據(jù)庫 Sqlite3 的 root 管理系統(tǒng)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.服務器

1.1服務器函數(shù)入口

#include "server.h"

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

    char buf[128] = {0};
    char buf_ID[256] = {0};
    // 接收報錯信息判斷
    sqlite3 *db;
    // 創(chuàng)建員工信息的表格,存在則打開
    db = Sqlite_Create();
    if (db == NULL)
    {
        printf("sqlite_create=NULL\n");
        return 0;
    }

    // 服務器 套接字->端口重啟->綁定->監(jiān)聽
    int sock_fd = sock_listen();
    if (!sock_fd)
    {
        printf("流程出現(xiàn)故障%d\n", __LINE__);
        return 0;
    }
    // 創(chuàng)建紅黑樹根節(jié)點
    //  創(chuàng)建一個epoll句柄/紅黑樹根節(jié)點
    epfd = epoll_create(10);

    if (epfd < 0)
    {
        printf("epoll_create on_success _%d_", __LINE__);
        return 0;
    }
    // 添加監(jiān)聽連接事件到紅黑樹節(jié)點中
    add_epoll(epfd, sock_fd);

    // 到此,以上流程全部正確走完
    // 客戶端信息結(jié)構體的大小
    socklen_t addrlen = sizeof(my_cin);

    /*********與客戶端互動區(qū)域_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返回就緒事件的個數(shù),并將就緒的事件放入到
        // events這個結(jié)構體中,參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++)
        {
            
            // 客戶端連接事件發(fā)生
            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;
                // 創(chuàng)建一個線程
                pthread_t tid;
                my_ser_cli.fd = events[i].data.fd;
                // 接收客戶端數(shù)據(jù),進入賬號密碼的判斷,是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登陸
                // 當事件發(fā)生以后移除文件描述符
                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線程創(chuàng)建失敗%d\n", tid, __LINE__);
                    return 0;
                }
                remove_fd(&my_ser_cli);//賬號下線,清楚其存在
            }
        }
    }
    /*********與客戶端互動區(qū)域_end*********/
    // 釋放資源
    return 0;
}

1.2服務器運行代碼

#include "server.h"
int flag = 0;
int fd_flag = 0;
// 創(chuàng)建數(shù)據(jù)庫并打開數(shù)據(jù)表
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;
    // 創(chuàng)建并打開數(shù)據(jù)庫
    sqlite3 *db = NULL;
    if (sqlite3_open("./staff.db", &db) != SQLITE_OK)
    {
        printf("sqlite3_open errno %d\n", __LINE__);
        return NULL;
    }
    debuf_db = db;
    // 組裝SQL語句創(chuàng)建數(shù)據(jù)表
    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;
}

// 服務器 套接字->端口重啟->綁定->監(jiān)聽
int sock_listen(void)
{
    // 一.創(chuàng)建套接字1.AF_INET默認為ip(7)協(xié)議 2.SOCK_STREAM默認為TCP
    // 3.0表示使用type對應的默認協(xié)議
    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;
    }
    // 填充服務器信息結(jié)構體
    my_ser.sin_family = AF_INET;            // IPv4協(xié)議指向填充
    my_ser.sin_port = htons(PORT);          // 將端口轉(zhuǎn)換成網(wǎng)絡字節(jié)
    my_ser.sin_addr.s_addr = inet_addr(IP); // IP地址轉(zhuǎn)換成網(wǎng)絡字節(jié)序
    // 綁定服務器的IP和端口
    if (bind(sock_fd, (struct sockaddr *)&my_ser, sizeof(my_ser)) < 0)
    {
        ERR_MSG("bind");
        goto OUT2;
    }
    // 將套接字設置為被動監(jiān)聽,最多監(jiān)聽128個
    if (listen(sock_fd, 128) < 0)
    {
        ERR_MSG("listen");
        goto OUT2;
    }
    return sock_fd;
OUT2:
    close(sock_fd);
OUT1:
    return 0;
}
// 紅黑樹監(jiān)聽事件信息的添加
int add_epoll(int epfd, int fd)
{
    // 將套接字的信息存入到event結(jié)構體中,為事件放入紅黑樹中做準備
    event.events = EPOLLIN; // 關注可讀事件,套接字有數(shù)據(jù)可讀時觸發(fā)
    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結(jié)構體中,為事件放入紅黑樹中做準備
    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.)
//      }
//  }
// 資源的釋放函數(shù)

// 創(chuàng)建一個線程處理客戶端交互
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;
                    // 將員工號存到數(shù)組里,用于歷史記錄查詢
                    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);
    // 判斷該賬號是否以及存在于數(shù)組
    for (int i = 0; i < 10; i++)
    {
        if (jobnumber_A[i].staff_information.jobnumber == my_ser_cli.staff_information.jobnumber) // 已經(jīng)在數(shù)組中
        {
            return 0; // 不做添加
        }
    }
    // 走到這里表示該賬號不存在數(shù)組中,添加
    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) // 表示工號已經(jīng)存在
            {
                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); // 發(fā)送歷史查詢記錄
            break;
        case 5:
            printf("管理系統(tǒng)退出成功\n");
            return 0;
            break;
        default:
            printf("輸入錯誤,請重新輸入\n");
            return 0;
            break;
        }
    }
}
// 服務器向root發(fā)送歷史記錄表
int root_lishi_user(ser_cli *my_ser_cli_H)
{
    printf("root調(diào)用歷史信息表\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++)
    {
        // 將存在的所有放到數(shù)組里面
        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) // 表示沒有找到,向服務器發(fā)送信息
        {
            printf("出現(xiàn)錯誤 工號不存在%d\n", __LINE__);
        }
        else
        {
            // 走到這里表示工號存在,將員工信息填充發(fā)送帶客戶端
            // 發(fā)送

            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("歷史記錄表成功發(fā)送\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) // 表示沒有找到,向服務器發(fā)送信息
        {
            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
        {
            // 走到這里表示工號存在,將員工信息填充發(fā)送帶客戶端
            // 發(fā)送

            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) // 表示沒有找到,向服務器發(fā)送信息
        {
            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,則修改成功
    // 判斷是根據(jù)<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) // 表示沒有找到,向服務器發(fā)送信息
        {
            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 // 走到這里,表示根據(jù)員工號找到對應的員工信息
        {
            key = 1;

            // 根據(jù)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) // 如果為假,表示失敗,發(fā)送失敗給客戶端
            {
                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) // 表示沒有找到,向服務器發(fā)送信息
        {
            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 // 走到這里,表示根據(jù)員工號找到對應的員工信息
        {

            key = 1;
            // 根據(jù)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) // 如果為假,表示失敗,發(fā)送失敗給客戶端
            {
                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: // 退出管理系統(tǒng)
            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;
    // 用戶登錄后添加賬號信息到數(shù)組中,判斷是否在線
    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__
/******頭文件區(qū)域*******/
#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>
/******引用區(qū)域*******/
// 創(chuàng)建數(shù)據(jù)庫并打開數(shù)據(jù)表
sqlite3 * Sqlite_Create(void);
// 服務器 套接字->端口重啟->綁定->監(jiān)聽
int sock_listen(void);
// 紅黑樹監(jiān)聽事件信息的添加
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   //順序表最大容量
// 信息結(jié)構體,因為使用IPv4,因此使用sockaddr_in填充bind的第二個參數(shù)
struct sockaddr_in my_ser; // 服務器信息結(jié)構體
struct sockaddr_in my_cin; // 保存客戶端信息結(jié)構體
// 員工信息結(jié)構體
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;
// 服務器與客戶端通信的結(jié)構體
typedef struct info
{
    int fd;//客戶端的描述符
    int CLI_SELECT;                // 登陸時選擇的操作 1管理員登陸,2是用戶登陸 3是退出
    int CLI_SELECT_H;  //登陸后選擇的操作 1.添加員工信息 2.修改員工記錄 3.查詢員工記 4.查詢歷史 5,退出管理
    int events_i;       //保存紅黑樹數(shù)組的下標
    int cli_n_p; //高賬號密碼權力的匹配程度,1表示賬號不存在2表示密碼不正確3表示不是特權4表示不是用戶5均成功
    int flag;//進入2級界面選項后,傳遞的自定義標志位
    sqlite3 *db;  
    str_staff staff_information; // 員工信息結(jié)構體
} ser_cli;
//客戶端發(fā)送信息
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); 
//添加員工信息到數(shù)組中
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);
//退出函數(shù)
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;
// 存放就緒事件描述符的數(shù)組
sqlite3 * debuf_db;
struct epoll_event events[10];
pthread_t tid;
int fd_A[10];
ser_cli jobnumber_A[10];
int epfd ;//紅黑樹根節(jié)點
#endif

2.客戶端代碼

2.1客戶端函數(shù)入口

#include "client.h"
int main(int argc, char const *argv[])
{
    // 創(chuàng)建套接字
    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; //通信結(jié)構體
    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:
            // 改變對應的結(jié)構體信息
            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:
            // 改變對應的結(jié)構體信息
            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:
            // 改變對應的結(jié)構體信息
            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客戶端執(zhí)行代碼

#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);
    // 根據(jù)接收到的信息判斷
    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("你的賬號正在登陸中\(zhòng)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("<*********管理操作系統(tǒng)********> 1\n");
        printf("<********1.添加員工信息*******> 1\n");
        printf("<********2.修改員工信息*******> 1\n"); // 兩種方式 工號 手機號
        printf("<********3.查詢員工信息*******> 1\n"); // 兩種方式 工號 手機號
        printf("<********4.查詢歷史記錄*******> 1\n");
        printf("<********5.退出管理系統(tǒng)*******> 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("管理系統(tǒng)退出成功\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("<*********員工操作系統(tǒng)********> 1\n");
        printf("<********1.查詢個人信息*******> 1\n");
        printf("<********2.修改個人信息*******> 1\n");
        printf("<********3.退出管理系統(tǒng)*******> 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;
    }
    // 服務器發(fā)來標志位,判斷賬號是否存在為1
    if (my_ser_cli.CLI_SELECT == 1)
    {
        printf("該工號已經(jīng)存在 %d\n", __LINE__);
        return 0;
    }
    if (my_ser_cli.staff_information.jobnumber)
    {
        printf("員工添加信息成功 %d\n", __LINE__);
    }
}
// root修改員工信息,將修改的數(shù)據(jù)發(fā)送到服務器
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;
    }
    // 接收消息是否修改成功,先改變?yōu)槭酥?    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;
    }
    // 服務器發(fā)來標志,如果成功則將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的值判斷根據(jù)什么查找
    // 重新保存
    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;
    }
    // 接收消息是否查詢成功,先改變?yōu)槭酥?    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;
    }
    // 服務器發(fā)來標志,如果成功則將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__
/******頭文件區(qū)域*******/
#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>
/******引用區(qū)域*******/
// 創(chuàng)建數(shù)據(jù)庫并打開數(shù)據(jù)表
sqlite3 * Sqlite_Create(void);
// 服務器 套接字->端口重啟->綁定->監(jiān)聽
int sock_listen(void);
// 紅黑樹監(jiān)聽事件信息的添加
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   //順序表最大容量
// 信息結(jié)構體,因為使用IPv4,因此使用sockaddr_in填充bind的第二個參數(shù)
struct sockaddr_in my_ser; // 服務器信息結(jié)構體
struct sockaddr_in my_cin; // 保存客戶端信息結(jié)構體
// 員工信息結(jié)構體
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;
// 服務器與客戶端通信的結(jié)構體
typedef struct info
{
    int fd;//客戶端的描述符
    int CLI_SELECT;                // 登陸時選擇的操作 1管理員登陸,2是用戶登陸 3是退出
    int CLI_SELECT_H;  //登陸后選擇的操作 1.查詢信息 2.修改密碼 3.查詢記錄
    int events_i;       //保存紅黑樹數(shù)組的下標
    int cli_n_p; //高賬號密碼權力的匹配程度,1表示賬號不存在2表示密碼不正確3表示不是特權4表示不是用戶5均成功
    int flag;//進入2級界面選項后,傳遞的自定義標志位
    sqlite3 *db; 
    str_staff staff_information; // 員工信息結(jié)構體
} ser_cli;
//客戶端發(fā)送信息
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); //輸出查詢到的結(jié)果
//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;
// 存放就緒事件描述符的數(shù)組
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)

文章來源地址http://www.zghlxwxcb.cn/news/detail-621703.html

到了這里,關于基于數(shù)據(jù)庫 Sqlite3 的 root 管理系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • sqlite3數(shù)據(jù)庫的實現(xiàn)

    sqlite3代碼實現(xiàn)數(shù)據(jù)庫的插入、刪除、修改、退出功能

    2024年02月12日
    瀏覽(22)
  • sqlite3將詞典導入數(shù)據(jù)庫

    使用sqlite3代碼實現(xiàn)將詞典導入數(shù)據(jù)庫中

    2024年02月12日
    瀏覽(25)
  • SQlite3數(shù)據(jù)庫相關相關命令

    SQlite3數(shù)據(jù)庫相關相關命令

    1. 創(chuàng)建表格 2. 插入數(shù)據(jù) 3. 查看數(shù)據(jù)庫記錄 4. 刪除信息 5. 更新數(shù)據(jù) 6. 增加一列 7. 刪除一列 (sqlite3 不支持直接刪除一列) 1. 打開數(shù)據(jù)庫 2. 關閉數(shù)據(jù)庫 3. 錯誤信息 4. 執(zhí)行一條sql語句 5. 查詢回調(diào)函數(shù) 6. 查詢函數(shù) 小知識:如果結(jié)構體中定義的是一級指針,那么你要定義變量取

    2024年02月16日
    瀏覽(28)
  • 02.sqlite3學習——嵌入式數(shù)據(jù)庫的基本要求和SQLite3的安裝

    02.sqlite3學習——嵌入式數(shù)據(jù)庫的基本要求和SQLite3的安裝

    目錄 嵌入式數(shù)據(jù)庫的基本要求和SQLite3的安裝 嵌入式數(shù)據(jù)庫的基本要求 常見嵌入式數(shù)據(jù)庫 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日
    瀏覽(29)
  • 【嵌入式數(shù)據(jù)庫之sqlite3】

    目錄 一.數(shù)據(jù)庫基本概念(理解) 1.數(shù)據(jù) 2.數(shù)據(jù)庫 二.常用的數(shù)據(jù)的數(shù)據(jù)庫(了解) 1.大型數(shù)據(jù)庫 2.中型數(shù)據(jù)庫 3.小型數(shù)據(jù)庫 三.基于嵌入式的數(shù)據(jù)庫(了解) 四.SQLite基礎(了解) 五.創(chuàng)建數(shù)據(jù)庫(熟練) 1.手工創(chuàng)建 2.代碼創(chuàng)建 六.SQLite編程接口 七.代碼示例(學生管理系統(tǒng)) 八

    2024年02月09日
    瀏覽(19)
  • 嵌入式數(shù)據(jù)庫之sqlite3

    嵌入式數(shù)據(jù)庫之sqlite3

    ????????數(shù)據(jù):能夠輸入計算機并能被計算機程序識別和處理的信息集合。 ????????數(shù)據(jù)庫:數(shù)據(jù)庫是在數(shù)據(jù)庫管理系統(tǒng)管理和控制之下,存放在存儲介質(zhì)上的數(shù)據(jù)集合。 1.大型數(shù)據(jù)庫 ????????Oracle公司是最早開發(fā)關系數(shù)據(jù)庫的廠商之一,其產(chǎn)品支持最廣泛的操作

    2024年02月10日
    瀏覽(22)
  • SQLite3數(shù)據(jù)庫的介紹和使用(面向業(yè)務編程-數(shù)據(jù)庫)

    SQLite是一種用C語言實現(xiàn)的的SQL數(shù)據(jù)庫 它的特點有:輕量級、快速、獨立、高可靠性、跨平臺 它廣泛應用在全世界范圍內(nèi)的手機電腦應用的內(nèi)建數(shù)據(jù)庫 官網(wǎng)地址:https://www.sqlite.org/index.html SQLite因為其采用文件存儲,且容易移植。在嵌入式中應用非常廣泛,可以說是嵌入式業(yè)

    2024年02月02日
    瀏覽(36)
  • 【C++】開源:sqlite3數(shù)據(jù)庫配置使用

    【C++】開源:sqlite3數(shù)據(jù)庫配置使用

    ?? ★,° :.☆( ̄▽ ̄)/$: .°★ ?? 這篇文章主要介紹sqlite3數(shù)據(jù)庫配置使用。 無專精則不能成,無涉獵則不能通?!簡⒊?歡迎來到我的博客,一起學習,共同進步。 喜歡的朋友可以關注一下,下次更新不迷路?? 項目Github地址: https://github.com/sqlite/sqlite SQLite 是一種嵌入式

    2024年02月14日
    瀏覽(20)
  • 用于將Grafana默認數(shù)據(jù)庫sqlite3遷移到MySQL數(shù)據(jù)庫

    用于將Grafana默認數(shù)據(jù)庫sqlite3遷移到MySQL數(shù)據(jù)庫

    以下是一個方案,用于將Grafana數(shù)據(jù)遷移到MySQL數(shù)據(jù)庫。 背景: grafana 默認采用的是sqlite3,當我們要以集群形式部署的時使用mysql較為方便,試了很多sqlite轉(zhuǎn)mysql的方法要么收費,最后放棄。選擇自己動手風衣足食。 目標: 遷移sqlite3切換數(shù)據(jù)庫到mysql 前提條件: 確保你已經(jīng)安裝了

    2024年02月20日
    瀏覽(25)
  • 10.1 嵌入式數(shù)據(jù)庫之sqlite3

    【1】數(shù)據(jù)庫 ? ?1, 數(shù)據(jù)庫的安裝 ? ? ? ?sudo dpkg -i ?*.deb ? ?2, 數(shù)據(jù)庫命令: ? ? ? 1)系統(tǒng)命令 , 都以\\\'.\\\'開頭 ? ? ? ? ?.exit? ? ? ? ? ?.quit ? ? ? ? ?.table ? 查看表 ? ? ? ? ?.schema ?查看表的結(jié)構 ? ? ? ? ?? ? ? ? 2)sql語句, 都以‘;’結(jié)尾 ? ? ? ? 1-- 創(chuàng)建一張表

    2024年02月12日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包