项目管理系统
创始人
2024-05-22 21:08:34
0

项目要求

1)服务器负责管理所有员工表单(以数据库形式),其他客户端可通过网络连接服务器来查询员工表单。

2)需要账号密码登陆,其中需要区分管理员账号还是普通用户账号。

3)管理员账号可以查看、修改、添加、删除员工信息,同时具有查询历史记录功能,管理员要负责管理所有的普通用户。

4)普通用户只能查询修改与本人有关的相关信息,其他员工信息不得查看修改。

5)服务器能同时相应多台客户端的请求功能。并发

项目涉及的知识点

1.TCP通信的服务器、客户端编程流程

        1.服务器:

                1)创建套接字

                2)绑定ip和端口号

                3)监听

                4)等待客户端连接

        2.客户端:

                1)创建套接字

                2)连接服务器

2.服务器并发

        1)多线程

        2)多进程

        3)IO多路复用:select

3.sqlite3数据库常用语句以及编程接口

        编译数据库接口相关c文件需要链接库 -lsqlite3

项目流程图

服务器

客户端

通信结构体的构建

/*员工基本信息*/
typedef struct staff_info{int  no;             //员工编号int  usertype;      //ADMIN 0    USER 1     char name[NAMELEN];    //姓名char passwd[8];     //密码int  age;             // 年龄char phone[NAMELEN];//电话char addr[DATALEN]; // 地址char work[DATALEN]; //职位char date[DATALEN];    //入职年月int level;            // 等级double salary ;        // 工资}staff_info_t;/*定义双方通信的结构体信息*/
typedef struct {int  msgtype;     //请求的消息类型int  usertype;    //ADMIN 0    USER 1       char username[NAMELEN];  //姓名char passwd[8];             //登陆密码char recvmsg[DATALEN];   //通信的消息int  flags;      //标志位void *released;staff_info_t info;      //员工信息
}MSG;

代码

头文件

 
#ifndef _COMMON_H_
#define _COMMON_H_#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #define STAFF_DATABASE 	 "staff_manage_system.db"#define USER_LOGIN 		0x00000000  // login	登陆    0x00000001
#define USER_MODIFY 	0x00000001  // user-modification  修改
#define USER_QUERY 		0x00000002  // user-query   查询#define ADMIN_LOGIN 	0x10000000  // login	         登陆    0x00000001
#define ADMIN_MODIFY 	0x10000001 // admin_modification 修改
#define ADMIN_ADDUSER 	0x10000002 // admin_adduser      添加
#define ADMIN_DELUSER 	0x10000004 // admin_deluser      删除
#define ADMIN_QUERY 	0x10000008  //hitory_query       查找
#define ADMIN_HISTORY 	0x10000010  //hitory_history     历史#define ADMIN_LIST      0x10000011 //列表#define QUIT 			0x11111111#define ADMIN 0	//管理员
#define USER  1	//用户#define PASSLEN 8
#define NAMELEN 16
#define DATALEN 128/*员工基本信息*/
typedef struct staff_info
{int  no; 					//员工编号int  usertype;  			//ADMIN 1	USER 2	 char name[NAMELEN];			//姓名char passwd[PASSLEN]; 		//密码int  age; 					// 年龄char phone[NAMELEN];		//电话char addr[DATALEN]; 		// 地址char work[DATALEN]; 		//职位char date[DATALEN];			//入职年月int level;					// 等级int salary;					// 工资}staff_info_t;/*定义双方通信的结构体信息*/
typedef struct 
{int  msgtype;       	 //请求的消息类型int  usertype;   		 //ADMIN 1	USER 2	   char username[NAMELEN];  //姓名char passwd[PASSLEN];	 //登陆密码char recvmsg[DATALEN];   //通信的消息int  flags;      		 //标志位staff_info_t info;       //员工信息
}MSG;#define S_IP "10.0.12.9"
#define IP "192.168.250.100"
#define PORT "8888"char user_name[NAMELEN];	 //姓名
char user_passwd[PASSLEN];	 //登陆密码char history[DATALEN+100];#endif

服务端

...

客户端

 
#include "common.h"int do_login(int socketfd);/***************************************函数名:do_query*参   数:消息结构体*功   能:管理员查询****************************************/
void do_admin_query(int sockfd, MSG *msg)
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = ADMIN_QUERY;char name[NAMELEN] = "";printf("Please enter find no:");scanf("%s", name);while (getchar() != '\n');strcpy(msg->recvmsg, name);//发送查询请求if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}//接受服务器响应while (1){recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "end", 3)){printf("find success\n");return;}if (!strncmp(msg->recvmsg, "no", 2)){printf("find error\n");return;}printf("----------------------------------\n");printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);printf("----------------------------------\n");}
}/***************************************函数名:admin_modification*参   数:消息结构体*功   能:管理员修改****************************************/
void do_admin_modification(int sockfd, MSG *msg) //管理员修改
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = ADMIN_MODIFY;int opt = 0;int tem;char str1[NAMELEN] = "";char str2[DATALEN] = "";char str3[PASSLEN] = "";printf("please enter user name:");scanf("%s",msg->username);printf("1:no\n2:usertype\n3:name\n4:passwd\n5:age\n6:phone\n7:addr\n8:work\n9:date\n10:level\n11:salary\nplease enter change option:");scanf("%d", &opt);while(getchar()!='\n');switch (opt){case 1:msg->flags = 1;printf("please enter no:");scanf("%d", &tem);msg->info.no = tem;break;case 2:msg->flags = 2;printf("please enter usertype:");scanf("%d", &tem);msg->info.usertype = tem;break;case 3:msg->flags = 3;printf("please enter name:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.name, str1);break;case 4:msg->flags = 4;printf("please enter passwd:");fgets(str3,PASSLEN,stdin);str3[strlen(str3)-1]='\0';strcpy(msg->info.passwd, str1);break;case 5:msg->flags = 5;printf("please enter age:");scanf("%d", &tem);msg->info.age = tem;break;case 6:msg->flags = 6;printf("please enter phone:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.phone, str1);break;case 7:msg->flags = 7;printf("please enter addr:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.addr, str2);break;case 8:msg->flags = 8;printf("please enter work:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.work, str2);break;case 9:msg->flags = 9;printf("please enter date:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.date, str2);break;case 10:msg->flags = 10;printf("please enter level:");scanf("%d", &tem);msg->info.level = tem;break;case 11:msg->flags = 11;printf("please enter salary:");scanf("%d", &tem);msg->info.salary = tem;break;default:printf("enter error\n");return;}if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}system("clear");recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "ok", 2)){printf("user change success\n");return;}else if(!strncmp(msg->recvmsg, "no", 2)){printf("user change error\n");return;}}/***************************************函数名:admin_adduser*参   数:消息结构体*功   能:管理员创建用户****************************************/
void do_admin_adduser(int sockfd, MSG *msg) //管理员添加用户
{system("clear");int tem;char str1[NAMELEN] = "";char str2[DATALEN] = "";char str3[PASSLEN] = "";memset(msg, 0, sizeof(MSG));msg->msgtype = ADMIN_ADDUSER;printf("please enter no:");scanf("%d", &tem);msg->info.no = tem;printf("please enter usertype:");scanf("%d", &tem);msg->info.usertype = tem;while (getchar() != '\n');printf("please enter name:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.name, str1);printf("please enter passwd:");fgets(str3,PASSLEN,stdin);str3[strlen(str3)-1]='\0';strcpy(msg->info.passwd, str3);printf("please enter age:");scanf("%d", &tem);msg->info.age = tem;while (getchar() != '\n');printf("please enter phone:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.phone, str1);printf("please enter addr:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.addr, str2);printf("please enter work:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.work, str2);printf("please enter date:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.date, str2);printf("please enter level:");scanf("%d", &tem);msg->info.level = tem;printf("please enter salary:");scanf("%d", &tem);msg->info.salary = tem;if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "ok", 2)){printf("user add success\n");return;}else if (!strncmp(msg->recvmsg, "no", 2)){printf("user add error\n");return;}printf("user add error\n");
}/***************************************函数名:admin_deluser*参   数:消息结构体*功   能:管理员删除用户****************************************/
void do_admin_deluser(int sockfd, MSG *msg) //管理员删除用户
{system("clear");msg->msgtype = ADMIN_DELUSER;int no = 0;printf("pelase enter delete user NO:");scanf("%d", &no);msg->info.no = no;if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "ok", 2)){printf("user delete success\n");return;}else if (!strncmp(msg->recvmsg, "no", 2)){printf("user delete error\n");return;}
}/***************************************函数名:do_history*参   数:消息结构体*功   能:管理员查看历史记录****************************************/
void do_admin_history(int sockfd, MSG *msg)
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = ADMIN_HISTORY;putchar(10);printf("   %s     |     %s     |                        %s                        \n","data","time","log");if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}while (1){recv(sockfd, msg, sizeof(MSG), 0);if (msg->flags == 1){printf("find success\n");break;}if (msg->flags == 2){printf("find error\n");break;}printf("%s",msg->recvmsg);send(sockfd, msg, sizeof(MSG), 0);}}void do_admin_list(int sockfd, MSG *msg)
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = ADMIN_LIST;char name[NAMELEN] = "";//发送查询请求if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}//接受服务器响应while (1){recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "endd", 4)){printf("find success\n");return;}if (!strncmp(msg->recvmsg, "no", 2)){printf("find error\n");return;}//printf("%d\t%d\t%s\t%s\t%d\t%s\t%s\t%s\t%s\t%d\t%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);printf("----------------------------------\n");printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);printf("----------------------------------\n");send(sockfd, msg, sizeof(MSG), 0);}
}/***************************************函数名:admin_menu*参   数:套接字、消息结构体*功   能:管理员菜单****************************************/
void admin_menu(int sockfd, MSG *msg)
{int op = -1;printf(" ************ 1  查看   ************\n");printf(" ************ 2  修改   ************\n");printf(" ************ 3  添加   ************\n");printf(" ************ 4  删除   ************\n");printf(" ************ 5  列表   ************\n");printf(" ************ 6  清屏   ************\n");printf(" ************ 7 历史记录 ************\n");printf(" ************ 0 退回上级 ************\n");printf("请输入选项:");scanf("%d", &op);while(getchar()!='\n');if(op < 0 || op > 7){system("clear");printf("输入错误 请重新输入\n");admin_menu(sockfd,msg);}switch (op){case 0:system("clear");do_login(sockfd);break;case 1:do_admin_query(sockfd, msg);break;case 2:do_admin_modification(sockfd, msg);break;case 3:do_admin_adduser(sockfd, msg);break;case 4:do_admin_deluser(sockfd, msg);break;case 5:do_admin_list(sockfd, msg);break;case 6:system("clear");break;case 7:do_admin_history(sockfd,msg);break;default:printf("enter error\n");return;}
}/***************************************函数名:do_query*参   数:消息结构体*功   能:用户查找****************************************/
void do_user_query(int sockfd, MSG *msg)
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = USER_QUERY;strcpy(msg->username, user_name);strcpy(msg->passwd,user_passwd);//发送查询请求if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}//接受服务器响应while(1){recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "end", 3)){printf("find success\n");return;}if (!strncmp(msg->recvmsg, "no", 2)){printf("find error\n");return;}printf("----------------------------------\n");printf("staffno :%d\nusertype:%d\nname    :%s\npasswd  :%s\nage     :%d\nphone   :%s\naddr    :%s\nwork    :%s\ndate    :%s\nlevel   :%d\nsalary  :%d\n", msg->info.no, msg->info.usertype, msg->info.name, msg->info.passwd, msg->info.age, msg->info.phone, msg->info.addr, msg->info.work, msg->info.date, msg->info.level, msg->info.salary);printf("----------------------------------\n");}
}/***************************************函数名:do_modification*参   数:消息结构体*功   能:用户修改****************************************/
void do_user_modification(int sockfd, MSG *msg)
{system("clear");memset(msg, 0, sizeof(MSG));msg->msgtype = USER_MODIFY;strcpy(msg->username, user_name);strcpy(msg->passwd,user_passwd);int opt = 0;int tem;char str1[NAMELEN] = "";char str2[DATALEN] = "";char str3[PASSLEN] = "";printf("1:no\n2:usertype(Please contact the administrator)\n3:name\n4:passwd\n5:age\n6:phone\n7:addr\n8:work\n9:date\n10:level\n11:salary\nplease enter change option:");scanf("%d", &opt);while(getchar()!='\n');switch (opt){case 1:msg->flags = 1;printf("please enter no:");scanf("%d", &tem);msg->info.no = tem;break;case 2:msg->flags = 2;printf("please enter usertype:");scanf("%d", &tem);msg->info.usertype = tem;break;case 3:msg->flags = 3;printf("please enter name:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.name, str1);break;case 4:msg->flags = 4;printf("please enter passwd:");fgets(str3,PASSLEN,stdin);str3[strlen(str3)-1]='\0';strcpy(msg->info.passwd, str3);break;case 5:msg->flags = 5;printf("please enter age:");scanf("%d", &tem);msg->info.age = tem;break;case 6:msg->flags = 6;printf("please enter phone:");fgets(str1,NAMELEN,stdin);str1[strlen(str1)-1]='\0';strcpy(msg->info.phone, str1);break;case 7:msg->flags = 7;printf("please enter addr:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.addr, str2);break;case 8:msg->flags = 8;printf("please enter work:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.work, str2);break;case 9:msg->flags = 9;printf("please enter date:");fgets(str2,DATALEN,stdin);str2[strlen(str2)-1]='\0';strcpy(msg->info.date, str2);break;case 10:msg->flags = 10;printf("please enter level:");scanf("%d", &tem);msg->info.level = tem;break;case 11:msg->flags = 11;printf("please enter salary:");scanf("%d", &tem);msg->info.salary = tem;break;default:printf("enter error\n");return;}if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return;}system("clear");recv(sockfd, msg, sizeof(MSG), 0);if (!strncmp(msg->recvmsg, "ok", 2)){printf("user change success\n");return;}else if(!strncmp(msg->recvmsg, "no", 2)){printf("user change error\n");return;}
}/***************************************函数名:user_menu*参   数:消息结构体*功   能:用户菜单****************************************/
void user_menu(int sockfd, MSG *msg)
{int op = -1;printf(" ************ 1  查看  ************\n");printf(" ************ 2  修改  ************\n");printf(" ************ 3  清屏  ************\n");printf(" ************ 0  退回上级  *********\n");printf("请输入选项:");scanf("%d", &op);while(getchar()!='\n');if(op < 0 || op > 3){system("clear");printf("输入错误 请重新输入\n");user_menu(sockfd,msg);}switch (op){case 0:system("clear");do_login(sockfd);break;case 1:do_user_query(sockfd, msg);break;case 2:do_user_modification(sockfd, msg);break;case 3:system("clear");break;default:printf("enter error\n");break;}
}int admin_or_user_login(int sockfd, MSG *msg)
{//输入用户名和密码memset(msg->username, 0, NAMELEN);printf("请输入用户名:");scanf("%s", msg->username);getchar();memset(msg->passwd, 0, DATALEN);printf("请输入密码: ");scanf("%s", msg->passwd);getchar();strcpy(user_name,msg->username);strcpy(user_passwd,msg->passwd);//发送登陆请求if (send(sockfd, msg, sizeof(MSG), 0) < 0){printf("Sending the account to the server error\n");return -1;}//接受服务器响应recv(sockfd, msg, sizeof(MSG), 0);//判断是否登陆成功if (strncmp(msg->recvmsg, "OK", 2) == 0){if (msg->usertype == ADMIN){system("clear");printf("亲爱的管理员,欢迎您登陆员工管理系统!\n");while (1){admin_menu(sockfd, msg);}}else if (msg->usertype == USER){system("clear");printf("亲爱的用户,欢迎您登陆员工管理系统!\n");while (1){user_menu(sockfd, msg);}}}else{printf("登陆失败!%s\n", msg->recvmsg);admin_or_user_login(sockfd,msg);}return 0;
}/*************************************************函数名:do_login*参   数:套接字、消息结构体*返回值:是否登陆成功*功   能:登陆*************************************************/
int do_login(int socketfd)
{int n;MSG msg;while (1){printf("**********************************\n");printf("********  1: 管理员模式   ********\n");printf("********  2:普通用户模式  ********\n");printf("********  0: 断开客户端    ********\n");printf("**********************************\n");printf("请输入您的选择(数字)>> ");scanf("%d", &n);while(getchar()!='\n');if(n < 0 || n > 2){system("clear");printf("输入错误 请重新输入\n");do_login(socketfd);}switch (n){case 1://管理员模式登录msg.msgtype = ADMIN_LOGIN; // 1msg.usertype = ADMIN;	   // 0break;case 2://普通用户登录msg.msgtype = USER_LOGIN;msg.usertype = USER;break;case 0://退出msg.msgtype = QUIT;if (send(socketfd, &msg, sizeof(MSG), 0) < 0){perror("do_login send");return -1;}close(socketfd);exit(0);default:printf("您的输入有误,请重新输入\n");}admin_or_user_login(socketfd, &msg);}
}int main(int argc, const char *argv[])
{// socket->填充->绑定->监听->等待连接->数据交互->关闭system("clear");int socketfd;//创建网络通信的套接字 流式套接字if (-1 == (socketfd = socket(AF_INET, SOCK_STREAM, 0))){printf("socket error\n");return -1;}printf("socket success\n");//填充网络结构体//填充服务器网路信息结构体struct sockaddr_in sin;//填充为IPV4地址sin.sin_family = AF_INET;//填充服务器IPsin.sin_addr.s_addr = inet_addr(IP);//填充服务器端口号sin.sin_port = htons(atoi(PORT));//连接服务器if (-1 == connect(socketfd, (struct sockaddr *)&sin, sizeof(sin))){printf("connect error\n");return -1;}printf("connect suceess\n");//登陆do_login(socketfd);//关闭套接字close(socketfd);return 0;
}

测试现象

Ubuntu 18.04 PZB - VMware

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...