员工管理系统

2023-05-16

头文件common.h

#ifndef __COMMON_H__
#define __COMMON_H__
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sqlite3.h>
#include <time.h>
#define MAX 256  //字符数组容量
//打印错误信息
#define ERR_MSG(msg)  do{\
	fprintf(stderr, " __%d__ ", __LINE__);\
	perror(msg);\
}while(0)
//获取当前时间日期
struct tm* getTime();
//员工信息包
typedef struct 
{
    int cmd;    // 功能码
    int id;     // 工号
    int age;    // 年龄
    char name[50];  // 名字
    char sex;       // 性别
    char department[20];    // 部门
    char phone[12];         // 手机号
    char passwd[50];        // 密码
}Msg_t;
//功能码
enum CMD
{
    ROOT_LOGIN,         //管理员登录
    USER_LOGIN,         //用户登录
    ADD_USER,           //添加用户
    DEL_USER,           //删除用户
    UPDATE_NAME,        //更新名字
    UPDATE_AGE,         //更新年龄
    UPDATE_SEX,         //更新性别
    UPDATE_DEPARTMENT,  //更新部门
    UPDATE_PHONE,       //更新号码
    UPDATE_PASSWD,      //更新密码
    FIND_ALL,           //查询所有用户信息
    FIND_ID,            //查询对应工号信息
    HISTORY,            //查看历史记录
};
//回收僵尸进程
void handler(int sig);
//判断管理员或用户输入的账号密码是否正确
int isLogin(Msg_t user, sqlite3* db, int newfd);
//管理员添加用户
int rootAddUser(Msg_t user, sqlite3* db, int newfd);
//管理员删除用户
int rootDelUser(Msg_t user, sqlite3* db, int newfd);
//更新用户信息
int rootUpdate(Msg_t user, sqlite3* db, int newfd);
//查询用户信息
int rootFind(Msg_t user, sqlite3* db, int newfd);
//查询历史数据
int rootHistory(Msg_t user, sqlite3* db, int newfd);
//登录菜单
unsigned int loginMenu();
//输入账号密码
Msg_t login(Msg_t user, int cmd);
//管理员菜单
unsigned int rootMenu();
//请求添加用户
int addUser(int sfd, Msg_t user);
//请求删除用户
int deleteUser(int sfd,Msg_t user);
//请求更新数据
int updateUser(int sfd, Msg_t user);
//请求查询用户信息
int findUser(int sfd, Msg_t user);
//请求查询历史操作记录
int history(int sfd, Msg_t user);
//普通用户菜单
unsigned int generalMenu();
#endif

功能文件 common.c

 

#include "./common.h"
//回收僵尸进程
void handler(int sig)
{
	while(waitpid(-1, NULL, WNOHANG) > 0);
	return;
}
//获取当前时间日期
struct tm* getTime()
{
    time_t t = time(NULL);

    struct tm* nowtime = NULL;
    nowtime = localtime(&t);
    //如果时间获取失败就重新获取
    while(nowtime == NULL)
    {
        t = time(NULL);
        nowtime = localtime(&t);
    }
    return nowtime;
}
//判断管理员或用户输入的账号密码是否正确
int isLogin(Msg_t user, sqlite3* db, int newfd)
{
	char sql[MAX]="";
	sprintf(sql, "select * from staffMessage where id=%d;",user.id);
	char** buf;
	int row;
	int column;
	if(sqlite3_get_table(db, sql, &buf, &row, &column, NULL)!= SQLITE_OK)
	{
		printf("查询失败\n");
		return -1;
	}      
	if(buf[7]==NULL)//无该账号
	{
		strcpy(sql, "id error");
	}else if((atoi(buf[7])==user.id) && (strcmp(buf[13],user.passwd)==0))//账号密码正确
	{
		strcpy(sql, "success");
	}else
	{
		strcpy(sql, "password error");//密码错误
	}
	//发送反馈信息
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}
//管理员添加用户
int rootAddUser(Msg_t user, sqlite3* db, int newfd)
{
	char sql[MAX]="";
	sprintf(sql, "insert into staffMessage values (%d,\"%s\",%d,'%c',\"%s\",\"%s\",\"%s\");",
			user.id,user.name,user.age,user.sex,user.department,user.phone,user.passwd);
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("添加用户失败\n");
		strcpy(sql,"添加失败");//反馈信息
	}else
	{
		printf("添加用户成功\n");
		//插入操作记录
		struct tm *time = getTime();
		sprintf(sql, "insert into history values (\"添加新用户 ID:%d\",\"%d/%d/%d %d:%d\",1234);", user.id,time->tm_year+1900,time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min);
		if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
		{
			printf("添加记录失败\n");
			return -1;
		}
		strcpy(sql,"添加成功");//反馈信息
	}
	//发送反馈信息
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}
//管理员删除用户
int rootDelUser(Msg_t user, sqlite3* db, int newfd)
{
	char sql[MAX]="";
	sprintf(sql, "delete from staffMessage where id=%d",user.id);
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("删除用户失败\n");
		strcpy(sql,"删除失败");//反馈信息
	}else
	{
		printf("删除用户成功\n");
		//插入操作记录
		struct tm *time = getTime();
		sprintf(sql, "insert into history values (\"删除用户  ID:%d\",\"%d/%d/%d %d:%d\",1234);", user.id,time->tm_year+1900,time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min);
		if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
		{
			printf("添加记录失败\n");
			return -1;
		}
		strcpy(sql,"删除成功");//反馈信息
	}
	//发送反馈信息
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}
//更新用户信息
int rootUpdate(Msg_t user, sqlite3* db, int newfd)
{
	char sql[MAX]="";
	switch (user.cmd)
	{
	case UPDATE_NAME:
		sprintf(sql, "update staffMessage set name=\"%s\" where id=%d",user.name, user.id);
		break;
	case UPDATE_AGE:
		sprintf(sql, "update staffMessage set age=%d where id=%d",user.age, user.id);
		break;
	case UPDATE_SEX:
		sprintf(sql, "update staffMessage set sex=\"%c\"  where id=%d",user.sex, user.id);
		break;
	case UPDATE_DEPARTMENT:
		sprintf(sql, "update staffMessage set department=\"%s\"  where id=%d",user.department, user.id);
		break;
	case UPDATE_PHONE:
		sprintf(sql, "update staffMessage set phone=\"%s\"  where id=%d",user.phone, user.id);
		break;
	case UPDATE_PASSWD:
		sprintf(sql, "update staffMessage set passwd=\"%s\"  where id=%d",user.passwd, user.id);
		break;
	default:
		break;
	}
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("修改用户信息失败\n");
		strcpy(sql,"修改失败");//反馈信息
	}else
	{
		printf("修改用户成功\n");
		//插入操作记录
		struct tm *time = getTime();
		sprintf(sql, "insert into history values (\"修改用户信息ID:%d\",\"%d/%d/%d %d:%d\",1234);", user.id,time->tm_year+1900,time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min);
		if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
		{
			printf("添加记录失败\n");
			return -1;
		}
		strcpy(sql,"修改成功");//反馈信息
	}
	//发送反馈信息
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
    return 0;
}
//查询用户信息
int rootFind(Msg_t user, sqlite3* db, int newfd)
{
    char sql[MAX]="";
    char** buf;
    int row;
    int column;
    int i;
	if(user.cmd == FIND_ID)
	{
		sprintf(sql, "select * from staffMessage where id=%d;", user.id);
		if(sqlite3_get_table(db, sql, &buf, &row, &column, NULL)!= SQLITE_OK)
		{
			printf("查询失败\n");
			return -1;
		}
		//只发生对应工号的所有数据
		for(i=7;i<(row+1)*column; i++)
		{
			if(send(newfd, buf[i], MAX, 0) < 0)
			{
				ERR_MSG("send");
				return -1;
			}
		}      
	}else
	{
		strcpy(sql, "select * from staffMessage;");
		if(sqlite3_get_table(db, sql, &buf, &row, &column, NULL)!= SQLITE_OK)
		{
			printf("查询失败\n");
			return -1;
		}
		for(i=14;i<(row+1)*column; i++)
		{
			if(send(newfd, buf[i], MAX, 0) < 0)
			{
				ERR_MSG("send");
				return -1;
			}
		} 
	}    
	//告诉客户端信息发送完成
	strcpy(sql,"finish");
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	struct tm *time = getTime();
	sprintf(sql, "insert into history values (\"查询用户信息\",\"\t%d/%d/%d %d:%d\",1234);",time->tm_year+1900,time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min);
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("添加记录失败\n");
		return -1;
	}
	return 0;
}
//查询历史数据
int rootHistory(Msg_t user, sqlite3* db, int newfd)
{
	char sql[MAX] = "select * from history;";
	char** buf;
	int row;
	int column;
	if(sqlite3_get_table(db, sql, &buf, &row, &column, NULL)!= SQLITE_OK)
	{
		printf("查询失败\n");
		return -1;
	}
	int i;
	for(i=0;i<(row+1)*column; i++)
	{
		if(send(newfd, buf[i], MAX, 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
	}      
	//发送反馈信息
	strcpy(sql,"finish");
	if(send(newfd, sql, sizeof(sql), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	struct tm *time = getTime();
	sprintf(sql, "insert into history values (\"查询历史记录\",\"\t%d/%d/%d %d:%d\",1234);",time->tm_year+1900,time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min);
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("添加记录失败\n");
		return -1;
	}
	return 0;
}
//登录菜单
unsigned int loginMenu()
{
    unsigned int chose;
    while(1)
    {
        printf("************员工管理系统************\n");
        printf("***********1.管理员模式************\n");
        printf("***********2.普通用户模式**********\n"); 
        printf("***********0.退出系统**************\n");
        printf("请输入您的选项:");
        scanf("%d",&chose);
        if(chose>2)
        {
            printf("输入有误,请重新输入\n");
        }else
        {
           return chose;
        }
		system("clear");//清屏
    }       
}
//输入账号密码
Msg_t login(Msg_t user, int cmd)
{
    user.cmd = cmd;
    printf("请输入工号:");
    scanf("%d",&user.id);
    while(getchar() != '\n');
    printf("请输入密码:");
    fgets(user.passwd, sizeof(user), stdin);
    user.passwd[strlen(user.passwd)-1] = '\0';
    return user;
}
//管理员菜单
unsigned int rootMenu()
{
    unsigned int chose;
    while(1)
    {
        printf("*************员工管理系统*************\n");
        printf("*************1.添加用户***************\n");
        printf("*************2.删除用户***************\n"); 
        printf("*************3.修改信息***************\n");
        printf("*************4.查看用户***************\n");
        printf("*************5.历史记录***************\n");
        printf("*************0.退出系统***************\n");
        printf("请输入您的选项:");
        scanf("%d",&chose);
        getchar();
        if(chose>5)
        {
            printf("输入有误,请重新输入\n");
        }else
        {
            return chose;
        }
		system("clear");//清屏
    }   
}
//请求添加用户
int addUser(int sfd, Msg_t user)
{
    user.cmd = ADD_USER;
    printf("请输入工号:");
    scanf("%d",&user.id);
    while(getchar() != '\n');

    printf("请输入名字:");
    fgets(user.name, sizeof(user), stdin);
    user.name[strlen(user.name)-1] = '\0';

    printf("请输入年龄:");
    scanf("%d",&user.age);
    while(getchar() != '\n');

    printf("请输入性别:");
    scanf("%c",&user.sex);
    while(getchar() != '\n');

    printf("请输入部门:");
    fgets(user.department, sizeof(user), stdin);
    user.department[strlen(user.department)-1] = '\0';

    printf("请输入号码:");
    fgets(user.phone, sizeof(user), stdin);
    user.phone[strlen(user.phone)-1] = '\0';

    printf("请输入密码:");
    fgets(user.passwd, sizeof(user), stdin);
    user.passwd[strlen(user.passwd)-1] = '\0';

    //发送数据包
	if(send(sfd, &user, sizeof(user), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
    //阻塞等待反馈信息
    char buf[MAX];
	if(recv(sfd, buf, sizeof(buf), 0) < 0)
	{
		return -1;
	}
    printf("%s\n",buf);
    return 0;
}
//请求删除用户
int deleteUser(int sfd,Msg_t user)
{
    user.cmd = DEL_USER;
    printf("请输入要删除的工号:");
    scanf("%d",&user.id);
    while(getchar() != '\n');
    //发送数据包
	if(send(sfd, &user, sizeof(user), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	//阻塞等待反馈信息
    char buf[MAX];
	if(recv(sfd, buf, sizeof(buf), 0) < 0)
	{
		return -1;
	}
    printf("%s\n",buf);
    return 0;
}
//请求更新数据
int updateUser(int sfd, Msg_t user)
{
    if(user.cmd == ROOT_LOGIN)
    {
        printf("请输入要修改员工的工号:");
        scanf("%d",&user.id);
        while(getchar() != '\n');
    }
    unsigned int chose;
    while(1)
    {
        do
        {
            printf("1:修改姓名\n2:修改年龄\n3:修改性别\n4:修改部门\n5:修改号码\n6:修改密码\n0:退出\n");
            printf("请输入选项:");
            scanf("%d",&chose);
            getchar();
        }while(chose>6);
        switch(chose)
        {
            case 0:
                return 0;
            case 1:
                user.cmd = UPDATE_NAME;
                printf("请输入名字:");
                fgets(user.name, 50, stdin);
                user.name[strlen(user.name)-1] = '\0';
                break;
            case 2:
                user.cmd = UPDATE_AGE;
                printf("请输入年龄:");
                scanf("%d",&user.age);
                while(getchar() != '\n');
                break;
            case 3:
                user.cmd = UPDATE_SEX;
                printf("请输入性别:");
                scanf("%c",&user.sex);
                while(getchar() != '\n');
                break;
            case 4:
                user.cmd = UPDATE_DEPARTMENT;
                printf("请输入部门:");
                fgets(user.department, sizeof(user), stdin);
                user.department[strlen(user.department)-1] = '\0';
                break;
            case 5:
                user.cmd = UPDATE_PHONE;
                printf("请输入号码:");
                fgets(user.phone, sizeof(user), stdin);
                user.phone[strlen(user.phone)-1] = '\0';
                break;
            case 6:
                user.cmd = UPDATE_PASSWD;
                printf("请输入密码:");
                fgets(user.passwd, sizeof(user), stdin);
                user.passwd[strlen(user.passwd)-1] = '\0';
                break;
        }
        //发送数据包
	    if(send(sfd, &user, sizeof(user), 0) < 0)
	    {
		    ERR_MSG("send");
		    return -1;
	    }
	    //阻塞等待反馈信息
        char buf[MAX];
	    if(recv(sfd, buf, sizeof(buf), 0) < 0)
	    {
		    return -1;
	    }
        printf("%s\n",buf);
        printf("是否继续修改 1:是 0:否\n");
        scanf("%d", &chose);
        getchar();
        if(!chose)
        {
            break;
        }
    }
    return 0;
}
//请求查询用户信息
int findUser(int sfd, Msg_t user)
{
	unsigned int chose;
	if(user.cmd == ROOT_LOGIN)
	{
		do{
			printf("1:查看所有员工信息\n2:指定工号查看\n0:退出\n请输入选项:");
			scanf("%d",&chose);
			getchar();
		}while(chose>2);
		switch (chose)
		{
		case 0:
			break;
		case 1:
			user.cmd = FIND_ALL;
			break;
		case 2:
			user.cmd = FIND_ID;
			printf("请输入工号:");
			scanf("%d",&user.id);
			getchar();
			break;
		default:
			break;
		}
	}else
	{
		user.cmd = FIND_ID;
	}
	//发送数据包
	if(send(sfd, &user, sizeof(user), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	//接收信息
	int i=0,res;
	char buf[MAX];
	while(1)
	{
		res = recv(sfd, buf, sizeof(buf), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
		if(strcmp(buf,"finish")==0)
		{
			break;
		}
		if(strlen(buf))
		{
			printf("%s\t",buf);
			i++;
		}
		if(i==7)
		{
			i=0;
			putchar(10);
		}   
	}
}
//请求查询历史操作记录
int history(int sfd, Msg_t user)
{
	user.cmd = HISTORY;
	//发送数据包
	if(send(sfd, &user, sizeof(user), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	int i=0,res;
	char buf[256];
	while(1)
	{
		res = recv(sfd, buf, sizeof(buf), 0);
		if(res < 0)
		{
			return -1;
		}
		if(strcmp(buf,"finish")==0)
		{
			break;
		}
		if(strlen(buf))
		{
			printf("%s\t",buf);
			i++;
		}
		if(i==3)
		{
			i=0;
			putchar(10);
		}   
	}
	putchar(10);
}
//普通用户菜单
unsigned int generalMenu()
{
    unsigned int chose;
	while(1)
	{
		printf("***********员工管理系统************\n");
		printf("*************1.查询***************\n");
		printf("*************2.修改***************\n");
		printf("*************0.退出***************\n");
		printf("请输入您的选项:");
		scanf("%d",&chose);
		if(chose>2)
		{
			printf("输入有误,请重新输入\n");
		}else
		{
			return chose;
		}
	}
}

服务器代码 server.c

#include "./common.h"
int main(int argc, char const *argv[])
{
    //回收僵尸进程
	if(SIG_ERR == signal(SIGCHLD, handler))
	{
		perror("signal");
		return -1;
	}

    //检查外部传参是否正确
    if(argc != 3)
    {
        printf("需外部传参 IP port\n");
        return -1;
    }
    //打开数据库
	sqlite3* db = NULL;
	if(sqlite3_open("./my.db", &db) != SQLITE_OK)
	{
		printf("打开数据库失败\n");
		return -1;
	}
	//创建一个表格,用于记录员工信息
	char* sql = "create table if not exists staffMessage (id int primary key, name char, age int, sex char, department char, phone char, passwd char);" ;
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("创建表失败\n");
		return -1;
	}
    //创建一个表,用于记录操作日志
	sql = "create table if not exists history (operation_note char, time char, id int);" ;
	if(sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK)
	{
		printf("创建表失败\n");
		return -1;
	}
    //默认管理员账号(ID:1   密码:admin)
    sql = "insert into staffMessage values (1,'root',0,'x',\"xxx\",\"xxx\",\"admin\");";
    sqlite3_exec(db, sql, NULL, NULL, NULL);
    
    //创建字节流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }
    //允许端口快速复用
    int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
    //填充服务器自身地址信息
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(atoi(argv[2]));
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    //绑定地址信息到套接字上
    if(bind(sfd, (struct sockaddr*)&sin,sizeof(sin))<0)
    {
        ERR_MSG("bind");
		return -1;
    }
    //设置为被动监听状态
    if(listen(sfd, 128)<0)
    {
        ERR_MSG("listen");
		return -1;
    }
    //接收客户端地址信息
    struct sockaddr_in cin;
    socklen_t cinLen = sizeof(cin); 
    //创建一个子进程,父进程用于接收客服端的套接字,子进程用户服务器与客户端通讯
    printf("准备就绪\n");
    while(1)
    {
        //获取用于通讯的套接字
        int newfd = accept(sfd,(struct sockaddr*)&cin, &cinLen);
        if(newfd<0)
        {
            ERR_MSG("accept");
		    return -1;
        }
        printf("[%s:%d]已连接\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
        pid_t pid = fork();
        if(pid<0)
        {
            ERR_MSG("fork");
            return -1;
        }else if(0 == pid)//子进程
        {
            char buf[MAX];
	        ssize_t res = 0;
            close(sfd);//关闭父进程中的套接字
		    //循环接收 
            Msg_t user;
            while(1)
            {
                bzero(buf, sizeof(buf));
		        res = recv(newfd, buf, sizeof(buf), 0);
		        if(res < 0)
		        {
			        ERR_MSG("recv");
			        return -1;
		        }
		        else if(0 == res)
		        {
			        printf("[%s:%d]退出连接\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
                    close(newfd);
			        exit(0);
		        }
                //转换消息包类型
                user = *(Msg_t*)buf;
                //解析数据包
                switch (user.cmd)
                {
                    case ROOT_LOGIN:
                    case USER_LOGIN:
                        isLogin(user, db, newfd);
                        break;
                    case ADD_USER:
                        rootAddUser(user, db, newfd);
                        break;
                    case DEL_USER:
                        rootDelUser(user, db, newfd);
                        break;
                    case UPDATE_NAME:
                    case UPDATE_AGE:
                    case UPDATE_SEX:
                    case UPDATE_DEPARTMENT:
                    case UPDATE_PHONE:
                    case UPDATE_PASSWD:
                        rootUpdate(user, db, newfd);
                        break;
                    case FIND_ALL:
                    case FIND_ID:
                        rootFind(user, db, newfd);
                        break;
                    case HISTORY:
                        rootHistory(user, db, newfd);
                        break;
                    default:
                        break;
                }
            }
        }
        close(newfd);//父进程关闭子进程中用于通信的套接字
    }	
    //接收信息
    //发送信息
    return 0;
}

客户端代码 client.c

#include "./common.h"

int main(int argc, char const *argv[])
{
    //检查外部传参是否正确
    if(argc != 3)
    {
        printf("需外部传参 IP port\n");
        return -1;
    }
    //创建字节流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }
    //允许端口快速复用
    int reuse = 1;
	if(0 > setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)))
	{
		ERR_MSG("setsockopt");
		return -1;
	}
    //填充服务器地址信息
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(atoi(argv[2]));
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    //连接服务器
    if(connect(sfd,(struct sockaddr*)&sin, sizeof(sin))<0)
    {
        ERR_MSG("connect");
		return -1;
    }
	char buf[MAX];
	ssize_t res;
    Msg_t user;
    unsigned int chose;
	while(1)
	{
        memset(&user, 0, sizeof(user));//清空信息包,避免干扰
        bzero(buf,sizeof(buf));//清空字符数组,避免干扰
        chose = loginMenu();
        switch(chose)
        {
            case 1:
                user = login(user, ROOT_LOGIN);
                break;
            case 2:
                user = login(user, USER_LOGIN);
                break;
            case 0:
                close(sfd);
                exit(0);
            default:
                close(sfd);
                exit(0);
        }
        //发送数据包
		if(send(sfd, &user, sizeof(user), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
		//接收反馈信息
		res = recv(sfd, buf, sizeof(buf), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
        printf("%s\n",buf);
        if(strcmp(buf, "success")==0)//登录成功
        {
            if(user.cmd==ROOT_LOGIN)//管理员登录成功
            {
                while(1)
                {
                    chose = rootMenu();
                    switch(chose)
                    {
                        case 0:
                            close(sfd);
                            exit(0);
                        case 1:
                            addUser(sfd, user);
                            break;
                        case 2:
                            deleteUser(sfd, user);
                            break;
                        case 3:
                            updateUser(sfd, user);
                            break;
                        case 4:
                            findUser(sfd, user);
                            break;
                        case 5:
                            history(sfd, user);
                            break;
                        default:
                            break;
                    }
                }
            }else//普通用户登录成功
            {
                while(1)
                {
                    chose = generalMenu(sfd,user);
                    switch(chose)
                    {
                        case 0:
                            close(sfd);
                            exit(0); 
                            break;
                        case 1:
                            findUser(sfd, user);
                            break;
                        case 2:
                            updateUser(sfd, user);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
	}
	close(sfd);
    //接收信息
    //发送信息 
    return 0;
}

 测试视频:

员工管理系统测试视频

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

员工管理系统 的相关文章

  • 【已解决】element-ui组件嵌套太多层,导致内部el-input和el-select 等组件无法正常输入解决方案

    如果 element ui 组件嵌套太多层 xff0c 可能会导致内部的 el input 和 el select 等组件无法正常输入 出现这种问题通常是由于 z index 属性设置不正确导致的 解决这个问题的方法是调整组件的 z ind
  • 两个半天一刷Ubuntu入门指令

    目录 两个半天一刷Ubuntu入门指令 一 Ubuntu初次体验 二 设备驱动 三 Ubuntu用户组及其权限分配 四 压缩解压 五 Linux连接文件 六 vim编辑器 七 Linux下C编程 八 gcc和make及其Makefile的引
  • ENV环境配置及其下载网络组件包问题

    准备工作 Env 工具包含了 RT Thread 源代码开发编译环境和软件包管理系统 从 RT Thread 官网下载 Env 工具 在电脑上装好 git xff0c 软件包管理功能需要 git 的支持 git 的下载地址为https gi
  • 芯片flash保护(解锁)

    报错结果 Error while accessing a target resource The resource is perhaps notavailable 就是无法下载程序 解决办法 1 下载ST LINK Utility 链接 x
  • 2.RTT-点灯大师的修炼

    1 创建工程模板 相信大家通过学习上一篇文章 1 RTT 环境搭建 现在能熟练的创建一个标准模板了 xff0c 如果不会就跳回去学习一下吧 链接 xff1a 1 RTT 环境搭建 嵌入式路上的流浪的博客 CSDN博客 建立好的工程模板编译并
  • 4.RTT-UART-中断接收及轮询发送

    本期博客开始分享RTT的UART xff0c 利用战舰V3的uart2来输入输出一些字符串 UART xff08 Universal Asynchronous Receiver Transmitter xff09 通用异步收发传输器 xff
  • 12.RTT-IIC设备-AHT10温湿度传感器

    本系列博客更新结束啦 xff01 完结啦 xff01 xff01 xff01 撒花 xff01 xff01 xff01 关于RTT的设备和驱动专题更新完毕啦 xff0c 本期是最后一期 一段学习旅途的结束意味着下一段学习冒险的开始 虽然本系
  • RTduino+sht31温湿度传感器

    本次博客使用的是STM32F103C8T6 xff0c 因为该BSP已经对接好RTduino了可以直接上手使用 一 RTduino简介 RTduino是RT Thread实时操作系统的Arduino生态兼容层 xff0c 为RT Threa
  • 一文揭秘字节跳动、华为、京东的薪资职级

    声明 xff1a 本文所有数字均不是官方数据 xff0c 为网络资料收集整理 字节跳动 01 全球员工总数 字节的员工数量目前超过5万人 图片来源 xff1a 字节范 02 岗位职级 字节跳动的职级研发序列一共10级 xff1a 字节跳动创
  • ESP_C3在ubuntu下运行RT-Thread

    1 clone源代码RT Thread git clone git 64 github com RT Thread rt thread git 2 开始搭建ESP IDF环境 进入源码到bsp文件夹下找到ESP32 C3 xff0c 开始配
  • uniapp中使用弹出层

    uniapp中使用弹出层 因为业务的需要 xff0c 需要弹出一个复选框 xff0c 使用uniapp中自带的框架 使用 xff1a 第一步 xff1a 下载下示例项目 xff0c 找到主要的文件夹 第二步 xff1a 将该文件夹放到组件的
  • 手写一个uniapp的步骤条组件

    span class token operator lt span template span class token operator gt span span class token operator lt span view span
  • uniapp中的分页

    数据量过多就会使用分页 第一种 xff1a API span class token comment 和data同级 span span class token function variable function onReachBotto
  • uniapp中生成随机的二维码并进行保存

    需求 xff1a 需要根据用户id的不同生成不同的二维码 xff0c 并进行本地保存 第一步 xff1a 下载插件 这里对于二维码的生成 xff0c 使用的是第三方插件weapp qrcode min js xff0c 主要用到的文件是 d
  • Pc端的基本Echarts

    Pc端的基本Echarts 双环传态图组件 span class token operator lt span template span class token operator gt span span class token oper
  • el-table表格的sortable排序的使用以及出现小数、%排序错乱

    前端实现排序 xff1a 只需要在表头上加上一个sortable属性即可 span class token tag span class token tag span class token punctuation lt span el t
  • 浏览器的回退和导航栏的选中转态不同步,路由在新窗口打开

    问题1 xff1a 浏览器的回退和导航栏的选中状态不能同步的问题 问题 xff1a 用户后退时候 xff0c 左边导航栏显示的还是上一个页面的导航 xff0c 但是路由和页面已经变了 span class token operator lt
  • 左右联动-左侧点击相应的位置,右侧随之滚动

    第一步 xff1a npm下载 npm install better scroll save 第二步 xff1a 局部注册 xff08 当前组件 xff09 span class token keyword import span BScr
  • 杂技-各种css小技巧

    渐变字体 background image webkit linear gradient bottom 379ED7 0FE2EE webkit background clip text webkit text fill color tra
  • 深入理解Kotlin无参构造函数

    Unsafe 创建实例 在java中 创建一个对象 其实主要就是3种方法 通过new 关键字来创建 这种是最常见的 通过反射构造方法来创建对象 这种也不少见 很多框架中都有使用 Unsafe类来创建实例 xff0c 这种情况非常少见 这里先

随机推荐