项目:屏幕信息推送系统

一、项目要求

1.一个root用户

权限有:屏幕管理,用户管理,日志管理

1)屏幕管理:

当新增一个屏幕,由PC管理端,编辑信息发送到linux服务端,linux服务端接收信息,服务端会修改数据库里的信息;主要有对屏幕的增删改查

屏幕信息主要包括屏幕位置、屏幕尺寸、屏幕厂商信息、屏幕序列号、屏幕安装时间等等

 

 2)用户管理

超级用户登陆后,可以增加用户,但不能删除用户(如果用户离职,指挥记录用户离职标记,后续无法再用此用户登录,直接删除会导致用户操作日志无法溯源),除此以外还包括了用户的改和查

用户信息包括:用户名、用户身份证信息、用户职位、用户手机号、用户邮箱、用户入职时间离职标记等等

 

 3)日志管理

可以查看日志

 2.普通用户

权限有:修改密码、查看在线屏幕、选择屏幕发送消息、选择屏幕发送文件

二、项目思路

需要搭建服务器端,客户端以及屏幕端,还要搭建服务器。

一个模块一个模块来写

 除此以外,还有客户端请求,服务端处理请求,日志,登录,链表,界面,数据库等等模块需要封装

在线屏幕以及用户信息将用链表储存(包括序列号/用户名和它们的套接字),每当客户端退出时,从在线链表里剔除对用客户端

三、代码

1.   .c文件

1)server.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/epoll.h>
#include <string.h>
#include "pack.h"
#include "mysql.h"
#include "log.h"
#include "list.h"
#include "deal_request.h"


//套接字初始化
int sock_init(){
    int sockfd;
    int ret;

    sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
    if(sockfd<0){
        perror("socket");
        return -1; 
    }   

    //设置套接字端口复用
    int opt = 1;
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    //设置地址族结构体
    struct sockaddr_in seraddr;
    int addrlen = sizeof(struct sockaddr_in);
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(6688);
    inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
    ret = bind(sockfd,(struct sockaddr*)&seraddr,addrlen);//绑定地址和端口号
    if(ret<0){
        perror("bind");
        return -1; 
    }   

    ret = listen(sockfd,10);//通知内核监听套接字
    if(ret<0){
        perror("listen");
        return -1; 
    }   

    return sockfd;//返回套接字
}

int main(){
    struct user_pk *head = NULL;
    head = create_node();//客户端链表,用来存储已经连接上的用户和它的套接字
    struct screen_pk *head1 = NULL;
    head1 =  create_node1();//屏幕端链表,用来存储已经连接上的屏幕和它的套接字
    int sockfd,ret,count,cfd,efd,port;
    char ip[64];
    struct sockaddr_in cliaddr;
    int addrlen = sizeof(struct sockaddr_in);
    //连接数据库
    ret = my_init();
    if(ret<0){
        return -1; 
    }   

    //epoll
    efd = epoll_create(100);//创建集合空间
    if(efd<0){
        perror("epoll_create");
        return -1; 
    }   

    //生成套接字
    sockfd = sock_init();
    if(sockfd<0){
        return -1; 
    }   

    struct epoll_event ev; 
    struct epoll_event evs[10];
    ev.events = EPOLLIN;
    ev.data.fd = sockfd;
    epoll_ctl(efd,EPOLL_CTL_ADD,sockfd,&ev);//管理集合空间中的文件描述符

    while(1){
        printf("服务器等待响应...\n");
        count = epoll_wait(efd,evs,10,-1);//监听集合中的文件描述符
        if(count<0){
            perror("epoll_wait");
            break;
        }

        for(int i=0;i<count;i++){
            int temp = evs[i].data.fd;
            if(temp == sockfd){  //有客户端请求连接
                //1.接受客户端
                cfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen);
                port = ntohs(cliaddr.sin_port);
                inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,64);
                printf("客户端[%s:%d]连接成功!\n",ip,port);
                if(cfd<0){
                    perror("accept");
                    continue;
                }
                //2.cfd加入efd关联集合中
                ev.data.fd = cfd;
                epoll_ctl(efd,EPOLL_CTL_ADD,cfd,&ev);
            }
            else{   //客户有请求
                struct pack pk; 
                ret = read(temp,&pk,sizeof(struct pack));//读包
                if(ret<0){
                    perror("read");
                    close(temp);  //关闭文件描述符
                    epoll_ctl(efd,EPOLL_CTL_DEL,temp,NULL); //从集合中移除
                    continue;
                }
                else if(ret == 0){ 
                    printf("客户端断开连接!\n");
                    close(temp); // 关闭文件描述符
                    epoll_ctl(efd,EPOLL_CTL_DEL,temp,NULL); //从集合中移除
                    if(head->next == NULL&&head1->next == NULL){ //每当客户或者屏幕断开连接时,将其从链表中剔除
                        continue;
                    }
                    else{ 
                        if(head->next!=NULL){
                            struct user_pk *p = head->next;
                            while(p!=NULL){
                                if(p->fd == temp){
                                    del_user_list(head,temp);
                                    break;
                                }
                                p = p->next;
                            }
                        }

                        if(head1->next!=NULL){
                            struct screen_pk *t =head1->next;
                            while(t!=NULL){
                                if(t->fd == temp){
                                    del_screen_list(head1,temp);
                                    break;
                                }
                                t = t->next;
                            }
                        }
                        continue;
                    }
                }

                if(pk.type == LOG){ //处理root用户登录请求
                    deal_root_login_request(temp,efd);
                }
                else if(pk.type == LOG2){  //处理普通用户登录请求
                    deal_user_login_request(temp,efd,head);
                }
                else if(pk.type == SCR_LOG){  //处理屏幕登录请求
                    deal_screen_login_request(temp,efd,head1);
                }
                else if(pk.type == SCR_ADD){   //处理增加屏幕请求
                    deal_add_screen_request(temp,efd);
                }
                else if(pk.type == SCR_DEL){  //处理删除屏幕请求
                    deal_del_screen_request(temp,efd);
                }
                else if(pk.type == SCR_MOD){  //处理修改屏幕请求
                    deal_mod_screen_request(temp,efd);
                }
                else if(pk.type == SCR_SHOW){  //处理展示屏幕请求
                    deal_show_screen_request(temp,efd);
                }
                else if(pk.type == USER_ADD){  //处理增加用户请求
                    deal_add_user_request(temp,efd);
                }
                else if(pk.type == USER_DEL){  //处理删除用户请求
                    deal_del_user_request(temp,efd);
                }
                else if(pk.type == USER_MOD){  //处理修改用户请求
                    deal_mod_user_request(temp,efd);
                }
                else if(pk.type == USER_SHOW){  //处理展示用户信息请求
                    deal_show_user_request(temp,efd);
                }
                else if(pk.type == USER_MOD_PSWD){  //处理用户修改密码请求
                    deal_mod_pswd_request(temp,efd,head);
                }
                else if(pk.type == SHOW_ON){  //处理展示当前在线屏幕请求
                    deal_show_online_screen_request(temp,efd,head1);
                }
                else if(pk.type == MESS){  //处理向屏幕发送消息请求
                    deal_message_request(temp,efd,head,head1);
                }
                else if(pk.type == SEND_FILE){ //处理向屏幕发送文件请求
                    deal_file_request(temp,efd,head,head1);
                }
            }
        }
    }   
    my_close();
    close(cfd);
    close(sockfd);
    free_user_pk(head);
    free_screen_pk(head1);
    return 0;
}

2)client.c


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include "pack.h"
#include "menu.h"
#include "login.h"
#include "list.h"
#include "client_request.h"

//打开root用户日志
void open_root_log(){
    int ch; 
    FILE *fp;
    char fname[50] = "./日志/root.log";

    fp = fopen(fname,"r");
    if(fp == NULL){
        printf("打开失败!\n");
        return;
    }   

    while((ch = getc(fp))!=EOF){
        putchar(ch);
    }   
    fclose(fp);
    return;
}
//打开普通用户日志
void open_user_log(){
    int ch; 
    FILE *fp;
    char fname[50] = "./日志/user.log";

    fp = fopen(fname,"r");
    if(fp == NULL){
        printf("打开失败!\n");
        return;
    }   

    while((ch = getc(fp))!=EOF){
        putchar(ch);
    }   
    fclose(fp);
    return;
}

void hangle(int sig){
    printf("rev sig:%d\n",sig);
}

int main(){
    signal(SIGPIPE,hangle);//遇到SIGPIPE信号执行hangle函数
    int sockfd,ret;
    int flag = 1;
    int sel,sel1,sel2,sel3,sel4,sel5;

    sockfd = socket(AF_INET,SOCK_STREAM,0);//创建监听套接字
    if(sockfd<0){
        perror("socket");
        return -1; 
    }   

    //设置地址族
    struct sockaddr_in seraddr;
    int addrlen = sizeof(struct sockaddr_in);
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(6688);
    inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
    ret = connect(sockfd,(struct sockaddr*)&seraddr,addrlen);//请求连接
    if(ret<0){
        perror("connect");
        return -1; 
    }   

    while(flag){
        int flag1 = 1;
        int flag5 = 1;
        menu1();
        scanf("%d",&sel);
        while(getchar()!='\n');
        switch(sel){
            case 1: //root用户登录
                ret = root_login_request(sockfd);
                if(ret == 1){  //登录成功进入下级操作页面
                    while(flag1){
                        int flag2 = 1;
                        int flag3 = 1;
                        int flag4 = 1;
                        menu2();
                        scanf("%d",&sel1);
                        while(getchar()!='\n');
                        switch(sel1){
                            case 1: //管理屏幕
                                while(flag2){
                                    menu3();
                                    scanf("%d",&sel2);
                                    while(getchar()!='\n');
                                    switch(sel2){
                                        case 1: //增加新屏幕
                                            add_screen_request(sockfd);
                                            break;
                                        case 2: //删除屏幕
                                            del_screen_request(sockfd);
                                            break;
                                        case 3: //修改屏幕
                                            mod_screen_request(sockfd);
                                            break;
                                        case 4: //查看所有屏幕信息
                                            show_screen_request(sockfd);
                                            break;
                                        case 0:
                                            flag2 = 0;
                                            break;
                                        default:
                                            printf("无效输入,请重新输入\n");
                                            break;
                                    }
                                }
                                break;
                            case 2: //管理用户
                                while(flag3){
                                    menu4();
                                    scanf("%d",&sel3);
                                    while(getchar()!='\n');
                                    switch(sel3){
                                        case 1: //增加新用户
                                            add_user_request(sockfd);
                                            break;
                                        case 2: //删除用户
                                            del_user_request(sockfd);
                                            break;
                                        case 3: //修改用户
                                            mod_user_request(sockfd);
                                            break;
                                        case 4: //查看所有用户信息
                                            show_user_request(sockfd);
                                            break;
                                        case 0:
                                            flag3 = 0;
                                            break;
                                        default:
                                            printf("无效输入,请重新输入\n");
                                            break;
                                    }
                                }
                                break;
                            case 3: //查看日志
                                while(flag4){
                                    menu5();
                                    scanf("%d",&sel4);
                                    while(getchar()!='\n');
                                    switch(sel4){
                                        case 1: //查看root用户日志
                                            open_root_log();
                                            break;
                                        case 2: //查看普通用户日志
                                            open_user_log();
                                            break;
                                        case 0:
                                            flag4 = 0;
                                            break;
                                        default:
                                            printf("无效输入,请重新输入\n");
                                            break;
                                    }
                                }
                                break;
                            case 0:
                                flag1 = 0;
                                break;
                            default:
                                printf("无效输入,请重新输入!\n");
                                break;
                        }
                    }
                }
                break;
            case 2: //普通用户登录
                ret = user_login_request(sockfd);
                if(ret == 1){ 
                    while(flag5){
                        menu6();
                        scanf("%d",&sel5);
                        while(getchar()!='\n');
                        switch(sel5){
                            case 1: //修改密码
                                mod_pswd_request(sockfd);
                                break;
                            case 2: //显示在线屏幕
                                show_online_screen(sockfd);
                                break;
                            case 3: //选择屏幕发送消息
                                choose_to_message(sockfd);
                                break;
                            case 4: //选择屏幕发送文件
                                choose_to_file(sockfd);
                                break;
                            case 0:
                                flag5 = 0;
                                break;
                            default:
                                printf("无效输入,请重新输入!\n");
                                break;
                        }
                    }
                }
                break;
            case 0:
                flag = 0;
                break;
            default:
                printf("无效输入,请重新输入!\n");
                break;
        }
    }   
    close(sockfd);
    return 0;
}

3)screen.c


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include "pack.h"

void hangle(int sig){
    printf("rev sig:%d\n",sig);
}

int main(){
    signal(SIGPIPE,hangle);
    int sockfd,ret;
    char number[18];
    
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0){
        perror("socket");
        return -1; 
    }   

    struct sockaddr_in seraddr;
    int addrlen = sizeof(struct sockaddr_in);
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(6688);
    inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
    ret = connect(sockfd,(struct sockaddr*)&seraddr,addrlen);
    if(ret<0){
        perror("connect");
        return -1; 
    }   


    struct pack pk; 
    pk.ver = 1;
    pk.type = SCR_LOG;
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));
    if(ret<0){
        perror("write");
        close(sockfd);
        exit(-1);
    }   

    printf("序列号:");
    scanf("%s",number);
    while(getchar()!='\n');

    ret = write(sockfd,number,strlen(number));
    if(ret<0){
        perror("write");
        close(sockfd);
        exit(-1);
    }   

    ret = read(sockfd,&pk,sizeof(struct pack));
    if(ret<0){
        perror("read");
        close(sockfd);
        exit(-1);
    }   
    else if(ret == 0){ 
        printf("服务器断开连接!\n");
        close(sockfd);
        exit(-1);
    }   

    if(pk.type == LOG_OK){
        printf("登录成功!\n");
    }   
    else if(pk.type == LOG_FAIL_NONAME){
        printf("登录失败,序列号不存在!\n");
        exit(-1);
    }   
    else if(pk.type == LOG_FLAG0){
        printf("该屏幕已拆除!\n");
        exit(-1);
    }   
    else if(pk.type == RELOG){
        printf("该屏幕已在线!\n");
        exit(-1);
    }   


    char buff[1024];
    while(1){
        ret = read(sockfd,buff,1024);
        if(ret<0){
            perror("read");
            close(sockfd);
            exit(-1);
        }
        else if(ret == 0){ 
            printf("服务器断开连接!\n");
            close(sockfd);
            exit(-1);
        }
        buff[ret] = '\0';
        printf("%s\n",buff);
    }   

    return 0;
}

4)deal_request.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "pack.h"
#include "mysql.h"
#include "log.h"
#include "list.h"

static void read_error(int ret,int cfd,int efd){
    if(ret<0){
        perror("read");
        close(cfd);
        epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
        return;
    }   
    else if(ret == 0){ 
        close(cfd);
        epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
        return;
    }   
}
static void write_error(int ret,int cfd,int efd){
    if(ret<0){
        perror("write");
        close(cfd);
        epoll_ctl(efd,EPOLL_CTL_DEL,cfd,NULL);
        return;
    }   
}
//处理root登录请求
int deal_root_login_request(int cfd,int efd){
    int ret;
    struct root r1; 
    ret = read(cfd,&r1,sizeof(struct root));
    read_error(ret,cfd,efd);

    struct pack pk; 
    pk.ver = 1;
    pk.type = LOG_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from root where 用户名='%s'",r1.name);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){ 
        pk.type = LOG_FAIL_NONAME;
    }   
    else{
        MYSQL_ROW row = NULL;
        row = mysql_fetch_row(result);
        if(strcmp(r1.name,row[0]) == 0){ 
            if(strcmp(r1.pswd,row[1]) == 0){ 
                pk.type = LOG_OK;
                sprintf(sql,"root用户[%s]登录系统",r1.name);
                log_root(sql);
            }
            else{
                pk.type = LOG_FAIL_WRONGPSWD;
            }
        }
    }   

    //将结果返回给客户端
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);

    return 0;
}
//处理用户登录请求
int deal_user_login_request(int cfd,int efd,struct user_pk *head){
    int ret;
    struct root r2; 
    ret = read(cfd,&r2,sizeof(struct root));
    read_error(ret,cfd,efd);

    struct pack pk; 
    pk.ver = 1;
    pk.type = LOG_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from user_info where 用户名='%s'",r2.name);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){ 
        pk.type = LOG_FAIL_NONAME;
    }   
    else{
        MYSQL_ROW row = NULL;
        for(int i=1;i<=rows;i++){
            row = mysql_fetch_row(result);
            int f = atoi(row[0]);
            if(strcmp(r2.name,row[1]) == 0){ 
                if(strcmp(r2.pswd,row[2]) == 0&&f == 1){ 
                    pk.type = LOG_OK;
                    struct user_pk *pnew = NULL;
                    pnew = create_node();
                    pnew->fd = cfd;
                    strcpy(pnew->name,r2.name);
                    pnew->next = head->next;
                    head->next = pnew;

                    sprintf(sql,"普通用户[%s]登录系统",r2.name);
                    log_user(sql);
                    break;
                }
                else if(strcmp(r2.pswd,row[2]) == 0&&f == 0){ 
                    pk.type = LOG_FLAG0;
                    break;
                }
                else{
                    pk.type = LOG_FAIL_WRONGPSWD;
                    break;
                }
            }
        }
    }   
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);

    return 0;
}
//处理增加新屏幕请求
int deal_add_screen_request(int cfd,int efd){
    int ret;
    struct screen s1; 
    ret = read(cfd,&s1,sizeof(struct screen));
    read_error(ret,cfd,efd);

    //将屏幕信息写入数据库
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"insert into screen_info values (%d,'%s','%s','%s','%s','%s')",\
            s1.flag,s1.num,s1.pos,s1.size,s1.firm,s1.settime);
    ret = my_go(sql,&result);
    if(ret == 0){ 
        sprintf(sql,"root用户admin增加了新屏幕,序列号为[%s]",s1.num);
        log_root(sql);
    }   
    struct pack pk; 
    pk.ver = 1;
    pk.type = SCR_ADD_OK;
    pk.len = 0;
    if(ret<0){
        pk.type = SCR_ADD_FAIL;
    }   

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}
//没有将数据从数据库彻底删除,而是将flag改为0
int deal_del_screen_request(int cfd,int efd){
    int ret;
    char number[18];
    ret = read(cfd,number,18);
    number[ret] = '\0';
    read_error(ret,cfd,efd);

    struct pack pk; 
    pk.ver = 1;
    pk.type = SCR_DEL_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from screen_info where 序列号='%s'",number);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){ 
        pk.type = SCR_DEL_FAIL;
        ret = write(cfd,&pk,sizeof(struct pack));
        write_error(ret,cfd,efd);
        return 0;
    }   
    else{
        MYSQL_ROW row = NULL;
        for(int i=1;i<=rows;i++){
            row = mysql_fetch_row(result);
            if(strcmp(number,row[1]) == 0){ 
                sprintf(sql,"update screen_info set flag=0 where 序列号='%s'",number);
                ret = my_go(sql,NULL);
                if(ret<0){
                    pk.type = SCR_DEL_FAIL;
                }
                else{
                    pk.type = SCR_DEL_OK;
                    sprintf(sql,"root用户admin删除了屏幕,序列号为[%s]",number);
                    log_root(sql);
                }
                break;
            }
        }
    }   
    //向客户端反馈
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}

//处理修改屏幕请求
int deal_mod_screen_request(int cfd,int efd){
    int ret;
    char number[18];
    struct screen s2; 
    ret = read(cfd,number,18);
    number[ret] = '\0';
    read_error(ret,cfd,efd);


    struct pack pk; 
    pk.ver = 1;  
    pk.type = SCR_MOD_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from screen_info where 序列号='%s'",number);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){ 
        pk.type = SCR_MOD_FAIL;
        ret == write(cfd,&pk,sizeof(struct pack));
        write_error(ret,cfd,efd);
        return 0;
    }   
    else{
        ret = read(cfd,&s2,sizeof(struct screen));
        read_error(ret,cfd,efd);
        sprintf(sql,"update screen_info set flag=%d where 序列号='%s'",s2.flag,number);
        my_go(sql,NULL);
        sprintf(sql,"update screen_info set 位置='%s' where 序列号='%s'",s2.pos,number);
        my_go(sql,NULL);
        sprintf(sql,"update screen_info set 尺寸='%s' where 序列号='%s'",s2.size,number);
        my_go(sql,NULL);
        sprintf(sql,"update screen_info set 厂商信息='%s' where 序列号='%s'",s2.firm,number);
        my_go(sql,NULL);
        sprintf(sql,"update screen_info set 安装时间='%s' where 序列号='%s'",s2.settime,number);
        my_go(sql,NULL);
        sprintf(sql,"update screen_info set 序列号='%s' where 序列号='%s'",s2.num,number);
        my_go(sql,NULL);

        sprintf(sql,"root用户admin修改了序列号为[%s]的屏幕,flag=[%d],位置=[%s],尺寸=[%s],厂商信息=[%s]\
                安装时间=[%s],序列号=[%s]",number,s2.flag,s2.pos,s2.size,s2.firm,s2.settime,s2.num);
        log_root(sql);
    }   

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}
//处理显示所有屏幕信息请求
int deal_show_screen_request(int cfd,int efd){
    int ret;
    struct screen s3;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from screen_info");
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    ret = write(cfd,&rows,sizeof(int));
    write_error(ret,cfd,efd);

    MYSQL_ROW row = NULL;
    for(int i=1;i<=rows;i++){
        row = mysql_fetch_row(result);
        s3.flag = atoi(row[0]);
        strcpy(s3.num,row[1]);
        strcpy(s3.pos,row[2]);
        strcpy(s3.size,row[3]);
        strcpy(s3.firm,row[4]);
        strcpy(s3.settime,row[5]);

        ret = write(cfd,&s3,sizeof(struct screen));
        write_error(ret,cfd,efd);

    }
    return 0;
}

//处理增加新用户请求
int deal_add_user_request(int cfd,int efd){
    int ret;
    struct user u1;
    ret = read(cfd,&u1,sizeof(struct user));
    read_error(ret,cfd,efd);

    //将用户信息写入数据库
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"insert into user_info values (%d,'%s','%s',%d,'%s',%d,'%s','%s')",\
            u1.flag,u1.name,u1.pswd,u1.iden,u1.pos,u1.phone,u1.mail,u1.hiredate);
    ret = my_go(sql,&result);
    if(ret == 0){
        sprintf(sql,"root用户admin增加了新用户,用户名为[%s]",u1.name);
        log_root(sql);
    }
    struct pack pk;
    pk.ver = 1;
    pk.type = USER_ADD_OK;
    pk.len = 0;
    if(ret<0){
        pk.type = USER_ADD_FAIL;
    }

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}
//没有将数据从数据库彻底删除,而是将flag改为0
int deal_del_user_request(int cfd,int efd){
    int ret;
    char name[32];
    ret = read(cfd,name,32);
    name[ret] = '\0';
    read_error(ret,cfd,efd);

    struct pack pk;
    pk.ver = 1;
    pk.type = USER_DEL_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from user_info where 用户名='%s'",name);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){
        pk.type = USER_DEL_FAIL;
        ret = write(cfd,&pk,sizeof(struct pack));
        write_error(ret,cfd,efd);
        return 0;
    }
    else{
        MYSQL_ROW row = NULL;
        for(int i=1;i<=rows;i++){
            row = mysql_fetch_row(result);
            if(strcmp(name,row[1]) == 0){
                sprintf(sql,"update user_info set flag=0 where 用户名='%s'",name);
                ret = my_go(sql,NULL);
                if(ret<0){
                    pk.type = USER_DEL_FAIL;
                }
                else{
                    pk.type = USER_DEL_OK;
                    sprintf(sql,"root用户admin删除了用户,用户名为[%s]",name);
                    log_root(sql);
                }
                break;
            }
        }
    }
    //向客户端反馈
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}

//处理修改用户请求
int deal_mod_user_request(int cfd,int efd){
    int ret;
    char name[32];
    ret = read(cfd,name,32);
    name[ret] = '\0';
    read_error(ret,cfd,efd);

    struct user u2;
    struct pack pk;
    pk.ver = 1;
    pk.type = USER_MOD_OK;
    pk.len = 0;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from user_info where 用户名='%s'",name);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){
        pk.type = USER_MOD_FAIL;
        ret == write(cfd,&pk,sizeof(struct pack));
        write_error(ret,cfd,efd);
        return 0;
    }
    else{
        ret = read(cfd,&u2,sizeof(struct user));
        read_error(ret,cfd,efd);
        sprintf(sql,"update user_info set flag=%d where 用户名='%s'",u2.flag,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 身份证=%d where 用户名='%s'",u2.iden,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 职位='%s' where 用户名='%s'",u2.pos,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 手机号=%d where 用户名='%s'",u2.phone,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 邮箱='%s' where 用户名='%s'",u2.mail,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 入职时间='%s' where 用户名='%s'",u2.hiredate,name);
        my_go(sql,NULL);
        sprintf(sql,"update user_info set 用户名='%s' where 用户名='%s'",u2.name,name);
        my_go(sql,NULL);

        sprintf(sql,"root用户admin修改了用户[%s]的信息,flag=[%d],身份证=[%d],职位=[%s],手机号=[%d],邮箱=[%s]\
                入职时间=[%s],用户名=[%s]",name,u2.flag,u2.iden,u2.pos,u2.phone,u2.mail,u2.hiredate,u2.name);
        log_root(sql);
    }

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}

//处理显示所有用户信息请求
int deal_show_user_request(int cfd,int efd){
    int ret;
    struct user u3;
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from user_info");
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    ret = write(cfd,&rows,sizeof(int));
    write_error(ret,cfd,efd);

    MYSQL_ROW row = NULL;
    for(int i=1;i<=rows;i++){
        row = mysql_fetch_row(result);
        u3.flag = atoi(row[0]);
        strcpy(u3.name,row[1]);
        u3.iden = atoi(row[3]);
        strcpy(u3.pos,row[4]);
        u3.phone = atoi(row[5]);
        strcpy(u3.mail,row[6]);
        strcpy(u3.hiredate,row[7]);

        ret = write(cfd,&u3,sizeof(struct user));
        write_error(ret,cfd,efd);

    }
    return 0;
}

//处理屏幕登录请求
int deal_screen_login_request(int cfd,int efd,struct screen_pk *head){
    int ret;
    int key = 0;
    char number[18];
    ret = read(cfd,number,18);
    number[ret] = '\0';
    read_error(ret,cfd,efd);

    struct screen_pk *p = head->next;
    struct pack pk;
    pk.ver = 1;
    pk.type = LOG_OK;
    pk.len = 0;
    while(p!=NULL){
        if(strcmp(p->num,number) == 0){
            key = 1;
            break;
        }
        p = p->next;
    }
    char sql[1024];
    int rows = 0;
    MYSQL_RES *result = NULL;
    sprintf(sql,"select *from screen_info where 序列号='%s'",number);
    my_go(sql,&result);
    rows = mysql_num_rows(result);
    if(rows == 0){
        pk.type = LOG_FAIL_NONAME;
    }
    else if(key == 1){
        pk.type = RELOG;
    }
    else{
        MYSQL_ROW row = NULL;
        for(int i=1;i<=rows;i++){
            row = mysql_fetch_row(result);
            int f = atoi(row[0]);
            if(strcmp(number,row[1]) == 0&&f == 1){
                pk.type = LOG_OK;
                sprintf(sql,"屏幕[%s]登录系统",number);
                log_user(sql);

                struct screen_pk *pnew = NULL;
                pnew = create_node1();
                pnew->fd = cfd;
                strcpy(pnew->num,number);
                pnew->next = head->next;
                head->next = pnew;
                break;
            }
            else if(strcmp(number,row[1]) == 0&&f == 0){
                pk.type = LOG_FLAG0;
                break;
            }
        }
    }
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
}

//处理用户修改密码请求
int deal_mod_pswd_request(int cfd,int efd,struct user_pk *head){
    struct user_pk *p = head->next;
    int ret;
    char pswd[18];
    char sql[1024];
    char name[32];
    while(p!=NULL){
        if(p->fd == cfd){
            strcpy(name,p->name);
            break;
        }
        p = p->next;
    }

    ret = read(cfd,pswd,18);
    pswd[ret] = '\0';
    read_error(ret,cfd,efd);

    struct pack pk;
    pk.ver = 1;
    pk.type = USER_MOD_PSWD_FAIL;
    sprintf(sql,"update user_info set 密码='%s' where 用户名='%s'",pswd,name);
    ret = my_go(sql,NULL);
    if(ret == 0){
        pk.type = USER_MOD_PSWD_OK;
        sprintf(sql,"用户[%s]修改了密码",name);
        log_user(sql);
    }

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}

//处理显示在线屏幕请求
int deal_show_online_screen_request(int cfd,int efd,struct screen_pk *head){
    int ret;
    struct screen_pk *p = head->next;
    struct pack pk;
    pk.ver = 1;
    pk.type = SHOW_ON;
    pk.len = len_screen_list(head);
    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);

    while(p!=NULL){
        ret = write(cfd,p,sizeof(struct screen_pk));
        write_error(ret,cfd,efd);
        p = p->next;
    }

    return 0;
}
//处理发送消息请求
int deal_message_request(int cfd,int efd,struct user_pk *head,struct screen_pk *head1){
    int ret,objfd;
    char number[18];
    char name[32];
    char buff[1024];
    char sql[1024];
    ret = read(cfd,number,18);
    read_error(ret,cfd,efd);
    number[ret] = '\0';

    struct pack pk;
    pk.ver = 1;
    pk.type = MESS_OK;
    pk.len = 0;
    struct user_pk *t = head->next;
    struct screen_pk *p = head1->next;
    while(t!=NULL){
        if(t->fd == cfd){
            strcpy(name,t->name);
            break;
        }
        t = t->next;
    }

    while(p!=NULL){
        if(strcmp(p->num,number) == 0){
            objfd = p->fd;
            break;
        }
        p = p->next;
    }

    ret = read(cfd,buff,1024);
    read_error(ret,cfd,efd);
    buff[ret] = '\0';

    ret = write(objfd,buff,strlen(buff));
    if(ret<0){
        close(objfd);
        pk.type = MESS_FAIL;
    }
    else{
        sprintf(sql,"用户[%s]向屏幕[%s]发送了信息为[%s]的消息",name,number,buff);
        log_user(sql);
    }
    usleep(100000);

    ret = write(cfd,&pk,sizeof(struct pack));
    write_error(ret,cfd,efd);
    return 0;
}

//处理发送文件的请求
int deal_file_request(int cfd,int efd,struct user_pk *head,struct screen_pk *head1){
    int ret,rfd,wfd,objfd;
    char number[18];
    char fname[50];
    char buff[1024];
    ret = read(cfd,number,18);
    read_error(ret,cfd,efd);
    number[ret] = '\0';

/*  ret = read(cfd,fname,50);
    read_error(ret,cfd,efd);
    fname[ret] = '\0';
    char sql[1024] = "./服务器文件夹/";
    char *t = strrchr(fname,'/');
    strcpy(sql,t);*/

    struct screen_pk *p = head1->next;
    while(p!=NULL){
        if(strcmp(p->num,number) == 0){
            objfd = p->fd;
            break;
        }
        p = p->next;
    }

    wfd = open("./服务器文件夹/data.txt",O_CREAT|O_WRONLY|O_TRUNC,0777);
    if(wfd<0){
        perror("open");
        return -1;
    }
    rfd = open("./服务器文件夹/data.txt",O_RDONLY);
    if(rfd<0){
        perror("open");
        return -1;
    }

    while(1){

    ret = read(cfd,buff,1024);
    read_error(ret,cfd,efd);

    ret = write(wfd,buff,ret);
    if(ret<0){
        perror("write");
        close(wfd);
        return -1;
    }

    ret = read(rfd,buff,1024);
    if(ret<0){
        perror("read");
        close(rfd);
        return -1;
    }
    ret = write(objfd,buff,ret);
    write_error(ret,cfd,efd);
    }

    close(wfd);
    close(rfd);
    return 0;
}

5)client_request.c

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "pack.h"
#include "login.h"
#include "list.h"



//读写异常处理函数
static void read_error(int ret,int sockfd){
    if(ret<0){
        perror("read");
        close(sockfd);
        exit(-1);
    }   
    else if(ret == 0){ 
        printf("服务器断开连接!\n");
        close(sockfd);
        exit(-1);
    }   
}

static void write_error(int ret,int sockfd){
    if(ret<0){
        perror("write");
        close(sockfd);
        exit(-1);
    }   
}

//增加新的屏幕
void add_screen_request(int sockfd){
    int ret,flag;
    struct screen s1; 
    while(1){
        printf("屏幕是否正在使用(1表示正在使用中,0表示不在使用中):");
        scanf("%d",&flag);
        while(getchar()!='\n');
        if(flag == 1||flag == 0){  //判断输入数字是否为1或0
            s1.flag = flag;
            break;
        }
        else{
            printf("请输入正确参数!\n");
        }
    }   
    printf("序列号:");
    scanf("%s",s1.num);
    while(getchar()!='\n');
    printf("位置:");
    scanf("%s",s1.pos);
    while(getchar()!='\n');
    printf("尺寸:");
    scanf("%s",s1.size);
    while(getchar()!='\n');
    printf("厂商信息:");
    scanf("%s",s1.firm);
    while(getchar()!='\n');
    printf("安装时间:");
    scanf("%s",s1.settime);
    while(getchar()!='\n');

    struct pack *p = NULL;
    p = (struct pack*)malloc(sizeof(struct pack)+sizeof(struct screen));
    assert(p!=NULL);

    p->ver = 1;
    p->type = SCR_ADD;//设置type
    p->len = sizeof(struct screen);
    memcpy(p->data,&s1,sizeof(struct screen));

    ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct screen));//发送包头和结构体
    write_error(ret,sockfd);

    ret = read(sockfd,p,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);

    if(p->type == SCR_ADD_OK){
        printf("增加新屏幕成功!\n");
    }
    else if(p->type == SCR_ADD_FAIL){
        printf("增加失败!\n");
    }
    else{
        printf("数据异常!\n");
    }
    free(p);
    return;
}

//删除屏幕
void del_screen_request(int sockfd){
    int ret;
    char number[18];
    printf("请输入需要删除的屏幕的序列号:");
    scanf("%s",number);
    while(getchar()!='\n');

    struct pack pk;
    pk.ver = 1;
    pk.type = SCR_DEL;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送包给服务器
    write_error(ret,sockfd);
    ret = write(sockfd,number,strlen(number));//发送序列号给服务器
    write_error(ret,sockfd);
    usleep(100000);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);

    //判断服务器的返回值
    if(pk.type == SCR_DEL_OK){
        printf("删除成功!\n");
    }
    else if(pk.type == SCR_DEL_FAIL){
        printf("删除失败!\n");
    }
    return;
}

//修改屏幕信息
void mod_screen_request(int sockfd){
    int ret,flag;
    char number[18];
    printf("请输入需要修改的屏幕序列号:");
    scanf("%s",number);
    while(getchar()!='\n');

    struct pack pk;
    pk.ver = 1;
    pk.type = SCR_MOD;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
    write_error(ret,sockfd);
    ret = write(sockfd,number,strlen(number));//发送序列号给服务器
    write_error(ret,sockfd);
    usleep(100000);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);
    if(pk.type == SCR_MOD_FAIL){
        printf("无此屏幕!\n");
        return;
    }

    struct screen s2;
    while(1){
        printf("是否启用该屏幕(1表示启用,0表示不启用):");
        scanf("%d",&flag);
        while(getchar()!='\n');
        if(flag == 1||flag == 0){ //确保修改的flag是0或1
            s2.flag = flag;
            break;
        }
        else{
            printf("请输入正确参数!\n");
        }
    }
    printf("请输入新的序列号:");
    scanf("%s",s2.num);
    while(getchar()!='\n');
    printf("请输入新的位置:");
    scanf("%s",s2.pos);
    while(getchar()!='\n');
    printf("请输入新的尺寸:");
    scanf("%s",s2.size);
    while(getchar()!='\n');
    printf("请输入新的厂商信息:");
    scanf("%s",s2.firm);
    while(getchar()!='\n');
    printf("请输入新的安装时间:");
    scanf("%s",s2.settime);
    while(getchar()!='\n');

    ret = write(sockfd,&s2,sizeof(struct screen));//将修改后的屏幕结构体发送给服务器
    write_error(ret,sockfd);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);
    if(pk.type == SCR_MOD_OK){
        printf("修改成功!\n");
    }
    else if(pk.type == SCR_MOD_FAIL){
        printf("修改失败!\n");
    }
    return;
}

//显示所有屏幕信息
void show_screen_request(int sockfd){
    int ret,len;
    struct pack pk;
    struct screen s3;
    pk.ver = 1;
    pk.type = SCR_SHOW;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//将空包发送给服务器
    write_error(ret,sockfd);

    ret = read(sockfd,&len,sizeof(int));//读取服务器返回的数据库里屏幕个数
    read_error(ret,sockfd);
    printf("在用/拆除\t序列号\t位置\t尺寸\t厂商信息\t安装时间\n");
    while(len){
        ret = read(sockfd,&s3,sizeof(struct screen));
        read_error(ret,sockfd);
        printf("%d\t%s\t%s\t%s\t%s\t%s\n",s3.flag,s3.num,s3.pos,s3.size,s3.firm,s3.settime);
        len--;
    }

    return;
}

//增加新的用户
void add_user_request(int sockfd){
    int ret,flag;
    struct user u1;
    while(1){
        printf("用户是否在职(1表示在职,0表示离职):");
        scanf("%d",&flag);
        while(getchar()!='\n');
        if(flag == 1||flag == 0){
            u1.flag = flag;
            break;
        }
        else{
            printf("请输入正确参数!\n");
        }
    }
    printf("用户名:");
    scanf("%s",u1.name);
    while(getchar()!='\n');
    printf("密码:");
    scanf("%s",u1.pswd);
    while(getchar()!='\n');
    printf("身份证:");
    scanf("%d",&u1.iden);
    while(getchar()!='\n');
    printf("职位:");
    scanf("%s",u1.pos);
    while(getchar()!='\n');
    printf("手机号:");
    scanf("%d",&u1.phone);
    while(getchar()!='\n');
    printf("邮箱:");
    scanf("%s",u1.mail);
    while(getchar()!='\n');
    printf("入职时间:");
    scanf("%s",u1.hiredate);
    while(getchar()!='\n');

    struct pack *p = NULL;
    p = (struct pack*)malloc(sizeof(struct pack)+sizeof(struct user));
    assert(p!=NULL);

    p->ver = 1;
    p->type = USER_ADD;//设置type
    p->len = sizeof(struct user);
    memcpy(p->data,&u1,sizeof(struct user));

    ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct user));//将包和用户信息结构体打包发送给服务器
    write_error(ret,sockfd);

    ret = read(sockfd,p,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);

    if(p->type == USER_ADD_OK){
        printf("增加新用户成功!\n");
    }
    else if(p->type == USER_ADD_FAIL){
        printf("增加失败!\n");
    }
    else{
        printf("数据异常!\n");
    }
    free(p);
    return;
}

//删除用户
void del_user_request(int sockfd){
    int ret;
    char name[32];
    printf("请输入需要删除的用户的用户名:");
    scanf("%s",name);
    while(getchar()!='\n');

    struct pack pk;
    pk.ver = 1;
    pk.type = USER_DEL;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
    write_error(ret,sockfd);
    ret = write(sockfd,name,strlen(name));//发送用户名给服务器
    write_error(ret,sockfd);
    usleep(100000);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);

    //判断服务器的返回值
    if(pk.type == USER_DEL_OK){
        printf("删除成功!\n");
    }
    else if(pk.type == USER_DEL_FAIL){
        printf("删除失败!\n");
    }
    return;
}

//修改用户信息
void mod_user_request(int sockfd){
    int ret,flag;
    char name[32];
    printf("请输入需要修改的用户:");
    scanf("%s",name);
    while(getchar()!='\n');

    struct pack pk;
    pk.ver = 1;
    pk.type = USER_MOD;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
    write_error(ret,sockfd);
    ret = write(sockfd,name,strlen(name));//发送用户名给服务器
    write_error(ret,sockfd);
    usleep(100000);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器发送的type
    read_error(ret,sockfd);
    if(pk.type == USER_MOD_FAIL){
        printf("无此用户!\n");
        return;
    }

    struct user u2;
    while(1){
        printf("该用户是否在职(1表示在职,0表示离职):");
        scanf("%d",&flag);
        while(getchar()!='\n');
        if(flag == 1||flag == 0){
            u2.flag = flag;
            break;
        }
        else{
            printf("请输入正确参数!\n");
        }
    }
    printf("请输入新的用户名:");
    scanf("%s",u2.name);
    while(getchar()!='\n');
    printf("请输入新的身份证:");
    scanf("%d",&u2.iden);
    while(getchar()!='\n');
    printf("请输入新的职位:");
    scanf("%s",u2.pos);
    while(getchar()!='\n');
    printf("请输入新的手机号:");
    scanf("%d",&u2.phone);
    while(getchar()!='\n');
    printf("请输入新的邮箱:");
    scanf("%s",u2.mail);
    while(getchar()!='\n');
    printf("请输入新的入职时间:");
    scanf("%s",u2.hiredate);
    while(getchar()!='\n');

    ret = write(sockfd,&u2,sizeof(struct user));//将修改后的用户信息结构体发送给服务器
    write_error(ret,sockfd);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);
    if(pk.type == USER_MOD_OK){
        printf("修改成功!\n");
    }
    else if(pk.type == USER_MOD_FAIL){
        printf("修改失败!\n");
    }
    return;
}
//显示所有用户信息
void show_user_request(int sockfd){
    int ret,len;
    struct pack pk;
    struct user u3;
    pk.ver = 1;
    pk.type = USER_SHOW;
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));
    write_error(ret,sockfd);

    ret = read(sockfd,&len,sizeof(int));//读取数据库里用户的个数
    read_error(ret,sockfd);
    printf("在职/离职\t用户名\t身份证\t职位\t手机号\t邮箱\t入职时间\n");
    while(len){
        ret = read(sockfd,&u3,sizeof(struct user));
        read_error(ret,sockfd);
        printf("%d\t%s\t%d\t%s\t%d\t%s\t%s\n",u3.flag,u3.name,u3.iden,u3.pos,u3.phone,u3.mail,u3.hiredate);
        len--;
    }

    return;
}

//普通用户修改密码
void mod_pswd_request(int sockfd){
    int ret;
    struct pack pk;
    pk.ver = 1;
    pk.type = USER_MOD_PSWD;
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));
    write_error(ret,sockfd);

    char pswd[18];
    printf("新密码:");
    scanf("%s",pswd);
    while(getchar()!='\n');

    ret = write(sockfd,pswd,strlen(pswd));
    write_error(ret,sockfd);

    ret = read(sockfd,&pk,sizeof(struct pack));
    read_error(ret,sockfd);
    if(pk.type == USER_MOD_PSWD_OK){
        printf("修改成功!\n");
    }
    else if(pk.type == USER_MOD_PSWD_FAIL){
        printf("修改失败!\n");
    }
    return;
}

//显示在线屏幕
void show_online_screen(int sockfd){
    int ret;
    struct screen_pk *head = NULL;
    struct pack pk;
    pk.ver = 1;
    pk.type = SHOW_ON;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
    write_error(ret,sockfd);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取在线屏幕的个数
    read_error(ret,sockfd);

    for(int i=0;i<pk.len;i++){ //将在线屏幕串成链表
        struct screen_pk *pnew =NULL;
        pnew = create_node1();
        ret = read(sockfd,pnew,sizeof(struct screen_pk));//读取在线屏幕的信息
        read_error(ret,sockfd);
        pnew->next = head;
        head = pnew;
    }

    struct screen_pk *p = head;
    printf("当前在线屏幕:\n");
    while(p!=NULL){
        printf("%s\n",p->num);
        p = p->next;
    }

    free_screen_pk(head);//结束销毁链表
    return;
}

//选择屏幕发送消息
void choose_to_message(int sockfd){
    char number[18];
    char buff[1024];
    int ret;
    struct pack pk;
    pk.ver = 1;
    pk.type = MESS;//设置type
    pk.len = 0;
    ret = write(sockfd,&pk,sizeof(struct pack));//发送空包给服务器
    write_error(ret,sockfd);

    printf("选择对象屏幕:");
    scanf("%s",number);
    while(getchar()!='\n');

    ret = write(sockfd,number,strlen(number));//发送选择的屏幕序列号
    write_error(ret,sockfd);
    usleep(100000);

    printf("请编辑发送的文字内容:\n");
    scanf("%s",buff);
    while(getchar()!='\n');

    ret = write(sockfd,buff,strlen(buff));//发送编辑的消息
    write_error(ret,sockfd);
    usleep(100000);

    ret = read(sockfd,&pk,sizeof(struct pack));//读取服务器返回的type
    read_error(ret,sockfd);
    if(pk.type == MESS_OK){
        printf("发送成功!\n");
    }
    else if(pk.type == MESS_FAIL){
        printf("发送失败!\n");
    }
}

//选择屏幕发送文件
void choose_to_file(int sockfd){
    char number[18];
    char fname[50];
    char buff[1024];
    int ret,rfd;
    struct pack pk;
    pk.ver = 1;
    pk.type = SEND_FILE;//设置type
    pk.len= 0;
    ret = write(sockfd,&pk,sizeof(struct pack));
    write_error(ret,sockfd);

    printf("选择对象屏幕:");
    scanf("%s",number);
    while(getchar()!='\n');
    ret = write(sockfd,number,strlen(number));
    write_error(ret,sockfd);
    usleep(100000);


    printf("输入发送的文件:\n");
    scanf("%s",fname);
    while(getchar()!='\n');
/*  ret = write(sockfd,fname,strlen(fname));
    write_error(ret,sockfd);
    usleep(100000);*/

    rfd = open(fname,O_RDONLY);//打开文件
    if(rfd<0){
        perror("open");
        exit(-1);
    }

    while(1){ //每次读1024个字节将整个文件传给服务器

    ret = read(rfd,buff,1024);
    if(ret<0){
        perror("read");
        close(rfd);
        exit(-1);
    }
    if(ret == 0){
        break;
    }

    ret = write(sockfd,buff,ret);
    write_error(ret,sockfd);
    }
    close(rfd);
    return;
}

6)login.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "pack.h"

    //将包头信息和root信息打包
    struct pack *p = NULL;
    p = (struct pack *)malloc(sizeof(struct pack)+sizeof(struct root));
    assert(p!=NULL);
    p->ver = 1;
    p->type = LOG;
    p->len = sizeof(struct root);
    memcpy(p->data,&r1,sizeof(struct root));

    //将打包的信息发送给服务器
    ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct root));
    if(ret<0){
        perror("write");
        close(sockfd);
        exit(-1);
    }   

    //读取服务器的反馈信息
    ret = read(sockfd,p,sizeof(struct pack));
    if(ret<0){
        perror("read");
        close(sockfd);
        exit(-1);
    }   
    else if(ret == 0){ 
        printf("服务器断开连接!\n");
        close(sockfd);
        exit(-1);
    }   
    //判断服务器反馈的type类型
    if(p->type == LOG_OK){
        printf("登录成功!\n");
        return 1;
    }   
    else if(p->type == LOG_FAIL_NONAME){
        printf("登录失败,用户名不存在!\n");
    }   
    else if(p->type == LOG_FAIL_WRONGPSWD){
        printf("登录失败,密码错误!\n");
    }
    else{
        printf("数据异常!\n");
    }
    free(p);
    return 0;
}


//普通用户密码登录功能
//成功返回1
//失败返回0
int user_login_request(int sockfd){
    int ret;
    struct root r2;
    printf("用户名:");
    scanf("%s",r2.name);
    while(getchar()!='\n');
    printf("密码:");
    scanf("%s",r2.pswd);
    while(getchar()!='\n');

    //将包头信息和root信息打包
    struct pack *p = NULL;
    p = (struct pack *)malloc(sizeof(struct pack)+sizeof(struct root));
    assert(p!=NULL);
    p->ver = 1;
    p->type = LOG2;
    p->len = sizeof(struct root);
    memcpy(p->data,&r2,sizeof(struct root));

    //将打包的信息发送给服务器
    ret = write(sockfd,p,sizeof(struct pack)+sizeof(struct root));
    if(ret<0){
        perror("write");
        close(sockfd);
        exit(-1);
    }

    //读取服务器的反馈信息
    ret = read(sockfd,p,sizeof(struct pack));
    if(ret<0){
        perror("read");
        close(sockfd);
        exit(-1);
    }
    else if(ret == 0){
        printf("服务器断开连接!\n");
        close(sockfd);
        exit(-1);
    }
    //判断服务器反馈的type类型
    if(p->type == LOG_OK){
        printf("登录成功!\n");
        return 1;
    }
    else if(p->type == LOG_FAIL_NONAME){
        printf("登录失败,用户名不存在!\n");
    }
    else if(p->type == LOG_FAIL_WRONGPSWD){
        printf("登录失败,密码错误!\n");
    }
    else if(p->type == LOG_FLAG0){
        printf("您的账户已注销!\n");
    }
    else{
        printf("数据异常!\n");
    }
    free(p);
    return 0;
}

7)log.c

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int log_root(char *str){
    int fd,ret;
    fd = open("/home/ssw/屏幕推送系统/日志/root.log",O_CREAT|O_APPEND|O_WRONLY,0777);//打开文件
    if(fd<0){
        return -1; 
    }   

    char temp[1024];

    time_t tm1;
    tm1 = time(NULL);

    struct tm *pt = NULL;
    pt = localtime(&tm1);

    sprintf(temp,"%d年%d月%d日  %d:%d:%d  %s\n",pt->tm_year+1900,pt->tm_mon+1,\
            pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec,str);

    ret = write(fd,temp,strlen(temp));
    if(ret<0){
        close(fd);
        return -1; 
    }   

    close(fd);
    return 0;
}

int log_user(char *str){
    int fd,ret;
    fd = open("/home/ssw/屏幕推送系统/日志/user.log",O_CREAT|O_APPEND|O_WRONLY,0777);
    if(fd<0){
        return -1; 
    }   

    char temp[1024];

    time_t tm1;
    tm1 = time(NULL);

    struct tm *pt = NULL;
    pt = localtime(&tm1);

    sprintf(temp,"%d年%d月%d日  %d:%d:%d  %s\n",pt->tm_year+1900,pt->tm_mon+1,\
            pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec,str);

    ret = write(fd,temp,strlen(temp));
    if(ret<0){
        close(fd);
        return -1; 
    }   

    close(fd);
    return 0;
}

8)mysql.c

#include "./mysql.h"
#include <stdio.h>


#define  HOST  "localhost"
#define  USER  "halfgod"
#define  PASSWD  "1"
#define  DB      "item_screen"



static  MYSQL  mysql;




//成功返回0, 失败返回-1
int my_init()
{
    //初始化句柄
    if(NULL == mysql_init(&mysql))
    {   
        printf("%s\n", mysql_error(&mysql));
        return -1; 
    }   

    //连接数据库
    if(NULL == mysql_real_connect(&mysql, HOST, USER, PASSWD, DB, 0, NULL, 0)) 
    {   
        printf("%s\n", mysql_error(&mysql));
        return -1; 
    }   
    mysql_set_character_set(&mysql, "utf8");
    return 0;
}


int my_go(char *sql, MYSQL_RES **pres)
{
    if(0!= mysql_query(&mysql, sql))
    {   
        printf("%s\n", mysql_error(&mysql));
        return -1; 
    }   

    MYSQL_RES  *result = NULL;
    result = mysql_store_result(&mysql);
    if(result != NULL)
    {   
        if(pres != NULL)
        {
            *pres = result;
        }
    }   
    return 0;
}


void my_close()
{
    mysql_close(&mysql);
}

9)list.c

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "pack.h"
//创建用户结点
struct user_pk *create_node(){
    struct user_pk *pnew = NULL;
    pnew = (struct user_pk *)malloc(sizeof(struct user_pk));
    assert(pnew!=NULL);
    pnew->next = NULL;
    return pnew;
}
//创建屏幕结点
struct screen_pk *create_node1(){
    struct screen_pk *pnew = NULL;
    pnew = (struct screen_pk *)malloc(sizeof(struct screen_pk));
    assert(pnew!=NULL);
    pnew->next = NULL;
    return pnew;
}
//释放用户链表
struct user_pk *free_user_pk(struct user_pk *head){
    struct user_pk *pdel = NULL;
    while(head!=NULL){
        pdel = head;
        head = head->next;
        free(pdel);
    }   
    return head;
}



static struct user_pk *search_user_list(struct user_pk *head,int cfd){
    struct user_pk *p = head->next;
    while(p!=NULL){
        if(p->fd == cfd){
            return p;
        }
        p = p->next;
    }   
}
//删除用户结点
void del_user_list(struct user_pk *head,int cfd){
    struct user_pk *pdel = search_user_list(head,cfd);
    struct user_pk *p = head;
    while(p->next!=pdel){
        p = p->next;
    }   
    p->next = pdel->next;
    free(pdel);
}

static struct screen_pk *search_screen_list(struct screen_pk *head,int cfd){
    struct screen_pk *p = head->next;
    while(p!=NULL){
        if(p->fd == cfd){
            return p;
        }
        p = p->next;
    }
}

//删除屏幕结点
void del_screen_list(struct screen_pk *head,int cfd){
    struct screen_pk *pdel = search_screen_list(head,cfd);
    struct screen_pk *p = head;
    while(p->next!=pdel){
        p = p->next;
    }
    p->next = pdel->next;
    free(pdel);
}
//求屏幕链表长度
int len_screen_list(struct screen_pk *head){
    int len = 0;
    struct screen_pk *p = head->next;
    while(p!=NULL){
        len++;
        p = p->next;
    }
    return len;
}
//释放屏幕链表
struct screen_pk *free_screen_pk(struct screen_pk *head){
    struct screen_pk *pdel = NULL;
    while(head!=NULL){
        pdel = head;
        head = head->next;
        free(pdel);
    }
    return head;
}

10)menu.c

#include <stdio.h>

void menu1(){
    printf("+----------------+\n");
    printf("|****用户登录****|\n");
    printf("|----------------|\n");
    printf("|   1.root用户   |\n");
    printf("|----------------|\n");
    printf("|   2.普通用户   |\n");
    printf("|----------------|\n");
    printf("|   0.退出系统   |\n");
    printf("+----------------+\n");
    printf("请选择:");
}

void menu2(){
    printf("+----------------+\n");
    printf("|****root用户****|\n");
    printf("|----------------|\n");
    printf("|   1.管理屏幕   |\n");
    printf("|----------------|\n");
    printf("|   2.管理用户   |\n");
    printf("|----------------|\n");
    printf("|   3.查看日志   |\n");
    printf("|----------------|\n");
    printf("|  0.返回上一层  |\n");
    printf("+----------------+\n");
    printf("请选择:");
}


void menu3(){
    printf("+----------------+\n");
    printf("|****管理屏幕****|\n");
    printf("|----------------|\n");
    printf("|  1.增加新屏幕  |\n");
    printf("|----------------|\n");
    printf("|   2.删除屏幕   |\n");
    printf("|----------------|\n");
    printf("|   3.修改屏幕   |\n");
    printf("|----------------|\n");
    printf("| 4.查看所有屏幕 |\n");
    printf("|----------------|\n");
    printf("|  0.返回上一层  |\n");
    printf("+----------------+\n");
    printf("请选择:");
}

void menu4(){
    printf("+----------------+\n");
    printf("|**管理普通用户**|\n");
    printf("|----------------|\n");
    printf("|  1.增加新用户  |\n");
    printf("|----------------|\n");
    printf("|   2.删除用户   |\n");
    printf("|----------------|\n");
    printf("|   3.修改用户   |\n");
    printf("|----------------|\n");
    printf("| 4.查看所有用户 |\n");
    printf("|----------------|\n");
    printf("|  0.返回上一层  |\n");
    printf("+----------------+\n");
    printf("请选择:");
}

void menu5(){
    printf("+------------------+\n");
    printf("|*****查看日志*****|\n");
    printf("|------------------|\n");
    printf("|1.查看root用户日志|\n");
    printf("|------------------|\n");
    printf("|2.查看普通用户日志|\n");
    printf("|------------------|\n");
    printf("|   0.返回上一层   |\n");
    printf("+------------------+\n");
    printf("请选择:");
}

void menu6(){
    printf("+------------------+\n");
    printf("|*****普通用户*****|\n");
    printf("|------------------|\n");
    printf("|    1.修改密码    |\n");
    printf("|------------------|\n");
    printf("|  2.查看在线屏幕  |\n");
    printf("|------------------|\n");
    printf("|3.选择屏幕发送消息|\n");
    printf("|------------------|\n");
    printf("|4.选择屏幕发送文件|\n");
    printf("|------------------|\n");
    printf("|   0.返回上一层   |\n");
    printf("+------------------+\n");
    printf("请选择:");
}

2.  .h文件

1)pack.h

#pragma once

//包头信息
struct pack{
    unsigned char ver;
    unsigned char type;
    unsigned char len;
    char data[0];
};

//表示root用户基本信息
struct root{
    char name[32];
    char pswd[18];
};

//表示普通用户基本信息
struct user{
    int flag;
    char name[32];
    char pswd[18];
    int iden;
    char pos[32];
    int phone;
    char mail[32];
    char hiredate[32];
};

//表示屏幕基本信息
struct screen{
    int flag;
    char num[18];
    char pos[32];
    char size[32];
    char firm[32];
    char settime[32];
};


struct user_pk{
    int fd; 
    char name[32];
    struct user_pk *next;
};
struct screen_pk{
    int fd; 
    char num[18];
    struct screen_pk *next;
};
#define LOG                1
#define LOG2               2
#define SCR_LOG            3
#define LOG_OK             4
#define RELOG              5
#define LOG_FLAG0          6
#define LOG_FAIL_NONAME    7
#define LOG_FAIL_WRONGPSWD 8

#define SCR_ADD            9
#define SCR_ADD_OK         10
#define SCR_ADD_FAIL       11
#define SCR_DEL            12
#define SCR_DEL_OK         13
#define SCR_DEL_FAIL       14
#define SCR_MOD            15
#define SCR_MOD_OK         16
#define SCR_MOD_FAIL       17
#define SCR_SHOW           18

#define USER_ADD           19
#define USER_ADD_OK        20
#define USER_ADD_FAIL      21
#define USER_DEL           22
#define USER_DEL_OK        23
#define USER_DEL_FAIL      24
#define USER_MOD           25
#define USER_MOD_OK        26
#define USER_MOD_FAIL      27
#define USER_SHOW          28
#define USER_MOD_PSWD      29 
#define USER_MOD_PSWD_OK   30
#define USER_MOD_PSWD_FAIL 31 

#define SHOW_ON            32

#define MESS               33
#define MESS_OK            34
#define MESS_FAIL          35

#define SEND_FILE          36
#define SEND_FILE_OK       37
#define SEND_FILE_FAIL     38

2)其他的 .h文件

3.Makefile文件

target: ser  cli  scr 

serobj = mysql.o  server.o  log.o  list.o  deal_request.o

cliobj = client.o  menu.o  login.o  list.o  client_request.o

scrobj = screen.o


ser:$(serobj)
    gcc $^  -o  $@  -lmysqlclient


cli:$(cliobj)
    gcc  $^  -o   $@  

scr:$(scrobj)
    gcc  $^   -o  $@

%.o : %.c 
    gcc  $^ -o $@  -c

clean:
    rm  -rf  *.o   cli  ser  scr

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值