功能:1.通过客户端,注册与登入员工管理系统(分普通与管理员模式)
2.普通权限功能:查询历史记录、查询全部员工信息
3.管理员权限功能:查询历史记录、查询全部员工信息,增加、修改、删除员工信息
思维构架图:
代码:
头文件work.h:
#ifndef __WORKER_H__
#define __WORKER_H__
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sqlite3.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <pthread.h>
#define MANAGE_WORKER "manage_worker.db"
#define NAMELEN 128
#define DATALEN 128
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
//员工基本信息框架
typedef struct manage{
int id;//工号
char name[NAMELEN];//姓名
int age;//年龄
char phone[10];//手机号
char addr[DATALEN];//地址
char work[DATALEN];//职位
char data[DATALEN];//入职日期
int level;//等级
double salary;//工资(年薪)
char data_history[20];//历史记录日期
char message_history[128];//行为
char show[4000];//数据库存储数据
}manage_t;
//通信信息结构体
typedef struct{
int msg_type;//请求的信息类型 1.注册|2.登入|3.增加|4.删|5.改|6.员工信息查询|7.历时记录查询
int user_type;//权限 0:admin 1:user
char user_name[NAMELEN];//用户名
char passwd[7];//密码,6位密码
int flags;//标志位 0:发送失败 1:发送成功
manage_t work;//员工的信息
}MSG;
//界面函数
void printf_HMI();//输入序号函数
void init_HMI();//初始界面:用户登入或注册
void login_HMI(MSG *msg);//登入信息填写界面
void register_HMI(MSG *msg);//注册信息填写界面
void user_power_HMI();//普通用户功能界面
void admin_power_HMI();//管理员用户功能界面
void change_worker_HMI(MSG *msg);//员工信息修改界面
void add_worker_HMI(MSG *msg);//员工信息添加界面
void delete_worker_HMI(MSG *msg);//员工信息删除界面
void delete_worker_old_HMI(MSG *msg);//旧员工信息删除界面
void show_worker_HMI(MSG *msg);//查看全部员工信息界面
void show_worker_history(MSG *msg);//查看历史记录信息界面
//数据库函数
int insert_seq_user(sqlite3 *db,MSG *msg);//用户信息插入
int insert_seq_worker(sqlite3 *db,MSG *msg);//员工信息插入
int insert_seq_history(sqlite3 *db,MSG *msg);//历史记录插入
int delete_seq_worker(sqlite3 *db,MSG *msg);//员工信息删除
int change_seq_worker(sqlite3 *db,MSG *msg);//员工信息修改
int search_seq_register(sqlite3 *db,MSG *msg,int *row,int *colum);//注册查询
int search_seq_user(sqlite3 *db,MSG *msg,int *row,int *colum);//用户查询
int search_seq_worker(sqlite3 *db,MSG *msg,int *row,int *colum);//员工查询
int show_seq_worker(sqlite3 *db,MSG *msg,int *row,int *colum);//员工信息展示
int show_seq_history(sqlite3 *db,MSG *msg,int *row,int *colum);//历史信息展示
//数据传输函数
int send_fun(int socketf,MSG *msg);//发送
int recv_fun(int socketf,MSG *msg);//接收
//标志位判断
int flags(MSG *msg);//0:未发送 1:发送成功 -1:错误
//主函数
int client_main(int socketf);//客户端主函数
int server_main(int newfd,struct sockaddr_in cin);//服务器主函数
#endif
客户端界面操作分文件HMI.c
#include "worker.h"
//输入序号函数
void printf_HMI()
{
printf("请输入需要的选项>>>\n");
}
//初始界面:用户登入或注册
void init_HMI()
{
printf("***************员工管理系统***************\n");
printf("1.用户注册\n");
printf("2.用户登入\n");
printf("3.退出\n");
printf("*****************************************\n");
printf_HMI();
}
//登入信息填写界面
void login_HMI(MSG *msg)
{
char name[128]="";
char passwd[20]="";
bzero(msg,sizeof(MSG));
printf("*****************登入界面*****************\n");
printf("请输入用户名>>>");
scanf("%s",msg->user_name);
while(strlen(passwd)!=6)
{
printf("请输入6位数的密码>>>");
scanf("%s",passwd);
getchar();
}
printf("请输入需要的权限0:普通用户 1:管理员>>>");
scanf("%d",&msg->user_type);
strcpy(msg->passwd,passwd);
msg->msg_type=2;//信息类型标为登入请求
}
//注册信息填写界面
void register_HMI(MSG *msg)
{
char name[128]="";
char passwd[20]="";
bzero(msg,sizeof(MSG));
printf("*****************注册界面*****************\n");
printf("请输入用户名>>>");
scanf("%s",msg->user_name);
printf("请输入需要的权限 0:普通用户 1:管理员>>>");
scanf("%d",&msg->user_type);
while(strlen(passwd)!=6)
{
printf("请输入6位数的密码>>>");
scanf("%s",passwd);
getchar();
}
strcpy(msg->passwd,passwd);
msg->msg_type=1;//信息类型标为注册请求
}
//普通用户功能界面
void user_power_HMI()
{
printf("*****************************************\n");
printf("0.退出\n");
printf("1.查看历史记录\n");
printf("2.查看全部员工信息\n");
}
//管理员用户功能界面
void admin_power_HMI()
{
user_power_HMI();
printf("3.添加员工信息\n");
printf("4.修改员工信息(姓名查询)\n");
printf("5.删除员工信息(姓名查询)\n");
}
//员工信息修改界面
void change_worker_HMI(MSG *msg)
{
printf("************员工信息修改界面************\n");
printf("1.请输入新的ID工号>>>");
scanf("%d",&msg->work.id);
printf("2.请输入原来的姓名>>>");
scanf("%s",msg->work.name);
printf("3.请输入新的年龄>>>");
scanf("%d",&msg->work.age);
printf("4.请输入新的手机号>>>");
scanf("%s",msg->work.phone);
printf("5.请输入新的地址>>>");
scanf("%s",msg->work.addr);
printf("6.请输入新的职位>>>");
scanf("%s",msg->work.work);
printf("7.请输入新的入职日期>>>");
scanf("%s",msg->work.data);
printf("8.请输入新的等级>>>");
scanf("%d",&msg->work.level);
printf("9.请输入新的工资(年薪)>>>");
scanf("%lf",&msg->work.salary);
msg->msg_type=3;//信息类型标为员工信息添加请求
printf("***************************************\n");
}
//员工信息添加界面
void add_worker_HMI(MSG *msg)
{
printf("1.请输入ID工号>>>");
scanf("%d",&msg->work.id);
printf("2.请输入姓名>>>");
scanf("%s",msg->work.name);
printf("3.请输入年龄>>>");
scanf("%d",&msg->work.age);
printf("4.请输入手机号>>>");
scanf("%s",msg->work.phone);
printf("5.请输入地址>>>");
scanf("%s",msg->work.addr);
printf("6.请输入职位>>>");
scanf("%s",msg->work.work);
printf("7.请输入入职日期>>>");
scanf("%s",msg->work.data);
printf("8.请输入等级>>>");
scanf("%d",&msg->work.level);
printf("9.请输入工资(年薪)>>>");
scanf("%lf",&msg->work.salary);
msg->msg_type=3;//信息类型标为员工信息添加请求
}
//员工信息删除界面
void delete_worker_HMI(MSG *msg)
{
printf("请输入需要删除员工信息的姓名>>>");
scanf("%s",msg->work.name);
msg->msg_type=4;//请求信息置删除位
}
//旧员工信息删除界面
void delete_worker_old_HMI(MSG *msg)
{
printf("请输入需要修改员工的姓名>>>");
scanf("%s",msg->work.name);
msg->msg_type=4;//请求信息置删除位
}
//查看全部员工信息界面
void show_worker_HMI(MSG *msg)
{
msg->msg_type=6;
}
//查看历史记录信息界面
void show_worker_history(MSG *msg)
{
msg->msg_type=7;
}
客户端与服务器间通信处理文件分fun.c
#include "worker.h"
//发送
int send_fun(int socketf,MSG *msg)
{
if(send(socketf,msg,sizeof(MSG),0)<0)
{
ERR_MSG("send");
return -1;
}
return 0;
}
//接收
int recv_fun(int socketf,MSG *msg)
{
if(recv(socketf,msg,sizeof(MSG),0)<0)
{
ERR_MSG("recv");
return -1;
}
return 0;
}
//标志位判断
int flags(MSG *msg)
{
if(msg->flags==1)
{
printf("发送成功\n");
msg->flags=0;
return 1;
}
else if(msg->flags==0)
{
printf("发送失败\n");
return 0;
}
else
{
printf("故障");
return -1;
}
}
服务器对.db文件处理分文件函数seq.c:
#include "worker.h"
//用户信息插入
int insert_seq_user(sqlite3 *db,MSG *msg)
{
char sql[1024]="";
sprintf(sql,"insert into user values (%d,'%s','%s');",msg->user_type,msg->user_name,msg->passwd);
char *errmsg;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return -1;
}
}
//员工信息插入
int insert_seq_worker(sqlite3 *db,MSG *msg)
{
char sql[1024]="";
sprintf(sql,"insert into worker values (%d,'%s',%d,'%s','%s','%s','%s',%d,%f);",\
msg->work.id,msg->work.name,msg->work.age,msg->work.phone,msg->work.addr,msg->work.work,msg->work.data,msg->work.level,msg->work.salary);
char *errmsg;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return 0;//插入失败
}
return 1;//插入成功
}
//历时记录插入
int insert_seq_history(sqlite3 *db,MSG *msg)
{
time_t t;
time(&t);
struct tm *info=localtime(&t);
sprintf(msg->work.data_history,"%d-%02d-%02d %02d:%02d:%02d",info->tm_year+1900,info->tm_mon+1,info->tm_mday,info->tm_hour,info->tm_min,info->tm_sec);
char sql[1024]="";
sprintf(sql,"insert into history values ('%s','%s','%s');",msg->work.data_history,msg->user_name,msg->work.message_history);
char *errmsg;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return 0;//插入失败
}
return 1;//插入成功
}
//员工信息删除
int delete_seq_worker(sqlite3 *db,MSG *msg)
{
char sql[1024]="";
sprintf(sql,"delete from worker where name=\"%s\";",msg->work.name);
char *errmsg;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return 0;//删除失败
}
return 1;//删除成功
}
//员工信息修改
int change_seq_worker(sqlite3 *db,MSG *msg)
{
char sql[1024]="";
sprintf(sql,"updata worker set id=%d age=%d phone=\"%s\" addr=\"%s\" work=\"%s\" data=\"%s\" level=%d salary=%f where name=\"%s\";",\
msg->work.id,msg->work.age,msg->work.phone,msg->work.addr,msg->work.work,msg->work.data,msg->work.level,msg->work.salary,msg->work.name);
char *errmsg;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
return -1;
}
}
//注册查询
int search_seq_register(sqlite3 *db,MSG *msg,int *row,int *colum)
{
char sql[1024]="";
char **pres=NULL;//储存查询到的字符串数组
char *errmsg;//错误信息
sprintf(sql,"select *from user where user_name=\"%s\";",msg->user_name);
if(sqlite3_get_table(db,sql,&pres,row,colum,&errmsg)!=SQLITE_OK)
{
return -1;
}
if(0==*row)
{
return 0;//查询不到
}
return 1;//查询到
}
//用户查询
int search_seq_user(sqlite3 *db,MSG *msg,int *row,int *colum)
{
char sql[1024]="";
char **pres=NULL;//储存查询到的字符串数组
char *errmsg;//错误信息
sprintf(sql,"select *from user where user_type=%d and user_name=\"%s\" and passwd=\"%s\";",msg->user_type,msg->user_name,msg->passwd);
if(sqlite3_get_table(db,sql,&pres,row,colum,&errmsg)!=SQLITE_OK)
{
return -1;
}
if(0==*row)
{
return 0;//查询不到
}
return 1;//查询到
}
//员工查询
int search_seq_worker(sqlite3 *db,MSG *msg,int *row,int *colum)
{
char sql[1024]="";
char **pres=NULL;//储存查询到的字符串数组
char *errmsg;//错误信息
sprintf(sql,"select *from user where user_name=\"%s\";",msg->work.name);
if(sqlite3_get_table(db,sql,&pres,row,colum,&errmsg)!=SQLITE_OK)
{
return -1;
}
if(0==*row)
{
return 0;//查询不到
}
return 1;//查询到
}
//员工信息展示
int show_seq_worker(sqlite3 *db,MSG *msg,int *row,int *colum)
{
int k=0;
int i,j;
char sql[1024]="";
char *errmsg;//错误信息
char **pres=NULL;//储存查询到的字符串数组
sprintf(sql,"select *from worker;");
if(sqlite3_get_table(db,sql,&pres,row,colum,&errmsg)!=SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_get_table: %s\n", __LINE__, errmsg);
return -1;
}
for(i=0;i<=*row;i++)
{
for(j=0;j<*colum;j++)
{
sprintf(msg->work.show+strlen(msg->work.show),"\t%s",pres[k++]);
}
strcat(msg->work.show,"\n");
}
return 1;
}
//历时信息展示
int show_seq_history(sqlite3 *db,MSG *msg,int *row,int *colum)
{
int k=0;
int i,j;
char sql[1024]="";
char *errmsg;//错误信息
char **pres=NULL;//储存查询到的字符串数组
sprintf(sql,"select *from history;");
if(sqlite3_get_table(db,sql,&pres,row,colum,&errmsg)!=SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_get_table: %s\n", __LINE__, errmsg);
return -1;
}
for(i=0;i<=*row;i++)
{
for(j=0;j<*colum;j++)
{
sprintf(msg->work.show+strlen(msg->work.show),"\t%s",pres[k++]);
}
strcat(msg->work.show,"\n");
}
return 1;
}
服务器构架server.c:
#include "worker.h"
#define PORT 8888
#define IP "192.168.250.100"
typedef void(*sighandler_t)(int);
void handler(int sig)
{
//回收僵尸进程
//回收成功则再回收一次,直到回收失败或没有回收为止
while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
//捕获17号信号
sighandler_t s=signal(17,handler);
if(SIG_ERR==s)
{
ERR_MSG("signal");
return -1;
}
//创建套接字
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(PORT);
sin.sin_addr.s_addr=inet_addr(IP);
//将地址信息绑定到套接字
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设为被动监听状态,让内核去监听是否有客户端连接
if(listen(sfd,10)<0)
{
ERR_MSG("listen");
return -1;
}
struct sockaddr_in cin;
socklen_t addrlen=sizeof(cin);
int newfd;
pid_t pid;
while(1)
{
//集合中文件描述符就绪
newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
pid=fork();
if(pid>0)//父进程运行
{
close(newfd);
}
else if(0==pid)//子进程只负责交互
{
close(sfd);
printf("success\n");
server_main(newfd,cin);//服务器主函数
close(newfd);
exit(0);
}
else
{
ERR_MSG("fork");
return -1;
}
}
close(sfd);
return 0;
}
服务器传输主要代码分文件server_main.c:
#include "worker.h"
int server_main(int newfd,struct sockaddr_in cin)
{
int tp;//接收发送过来数据包的请求数据类型
//打开表格
sqlite3 *history=NULL;
sqlite3 *user=NULL;
sqlite3 *worker=NULL;
sqlite3_open("./user.db",&history);
sqlite3_open("./user.db",&user);
sqlite3_open("./user.db",&worker);
//sqlite3_exec错误信息指针
char *errmsg=NULL;
MSG msg;
int row=0,colum=0;
while(1)
{
bzero(&msg,sizeof(MSG));//清空
recv_fun(newfd,&msg);//接收
tp=msg.msg_type;
row=0;
colum=0;
switch(tp)
{
case 1://注册
if(search_seq_register(user,&msg,&row,&colum)==0)//查询得知账户名未被注册
{
if(insert_seq_user(user,&msg)<0)//提交服务器发过来的注册账户信息
{
return -1;
}
msg.flags=1;//注册成功
bzero(msg.work.message_history,sizeof(msg.work.message_history));
sprintf(msg.work.message_history,"注册成功");
insert_seq_history(history,&msg);
}
break;
case 2://登入
if(search_seq_user(user,&msg,&row,&colum)==1)//查询有对应用户信息
{
bzero(msg.work.message_history,sizeof(msg.work.message_history));
sprintf(msg.work.message_history,"%s登入成功",msg.user_name);
insert_seq_history(history,&msg);
msg.flags=1;//登入成功
}
break;
case 3://员工信息插入
if(insert_seq_worker(worker,&msg)==1)
{
bzero(msg.work.message_history,sizeof(msg.work.message_history));
sprintf(msg.work.message_history,"%s员工信息修改成功",msg.work.name);
insert_seq_history(history,&msg);
msg.flags=1;//添加成功
}
break;
case 4://员工信息删除
if(delete_seq_worker(worker,&msg)==1)
{
bzero(msg.work.message_history,sizeof(msg.work.message_history));
sprintf(msg.work.message_history,"%s员工信息删除成功",msg.work.name);
insert_seq_history(history,&msg);
msg.flags=1;//删除成功
}
break;
case 5://员工信息修改
break;
case 6://员工信息查询
if(show_seq_worker(worker,&msg,&row,&colum)==1)
{
msg.flags=1;//查询成功
}
break;
case 7://历时记录查询
if(show_seq_history(worker,&msg,&row,&colum)==1)
{
msg.flags=1;//查询成功
}
break;
default:
break;
}
send_fun(newfd,&msg);//发送
}
//关闭数据库
sqlite3_close(history);
sqlite3_close(user);
sqlite3_close(worker);
return 0;
}
客户端构架client.c:
#include "worker.h"
#define PORT 8888
#define IP "192.168.250.100"
int main(int argc, const char *argv[])
{
MSG msg;
//创建套接字
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(PORT);
sin.sin_addr.s_addr=inet_addr(IP);
//连接服务器
if(connect(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("connect");
return -1;
}
client_main(sfd);
//关闭套接字
close(sfd);
return 0;
}
客户端传输主要代码分文件client_main.c:
#include "worker.h"
int client_main(int socketf)
{
int x,y;//选项号
int fla;//界面标志位0:初始界面|1:功能界面
MSG msg;
while(fla!=2)
{
fla=0;//置初始位
init_HMI();//初始界面:用户登入或注册
scanf("%d",&x);
getchar();
switch(x)
{
case 1://用户注册
register_HMI(&msg);//注册信息填写界面
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
break;
case 2://用户登入
login_HMI(&msg);//登入信息填写界面
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
if(fla==1)
{
fla=2;//标志位,2时,用户信息验证通过
}
break;
case 3://退出
goto END;
break;
default:
break;
}
}
//运行到这里,说明用户已经登入
y=10;//选项位置空
while(msg.user_type==0&&y!=0)//普通用户登入后界面
{
user_power_HMI();
printf_HMI();
scanf("%d",&y);
switch(y)
{
case 0://退出
break;
case 1://查看历史记录
show_worker_history(&msg);
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
printf("%s\n",msg.work.show);
bzero(msg.work.show,sizeof(msg.work.show));//清空
break;
case 2://查看全部员工信息
show_worker_HMI(&msg);
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
printf("%s\n",msg.work.show);
bzero(msg.work.show,sizeof(msg.work.show));//清空
break;
default:
break;
}
}
while(msg.user_type==1&&y!=0)//管理员登入后界面
{
admin_power_HMI();
printf_HMI();
scanf("%d",&y);
switch(y)
{
case 0://退出
break;
case 1://查看历史记录
show_worker_history(&msg);
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
printf("%s\n",msg.work.show);
bzero(msg.work.show,sizeof(msg.work.show));//清空
break;
case 2://查看全部员工信息
show_worker_HMI(&msg);
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
printf("%s\n",msg.work.show);
bzero(msg.work.show,sizeof(msg.work.show));//清空
break;
case 3://添加员工信息
add_worker_HMI(&msg);//员工信息添加界面
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
break;
case 4://修改员工信息(姓名查询)(先删后插)
delete_worker_old_HMI(&msg);//旧员工信息删除
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
change_worker_HMI(&msg);//员工信息修改界面
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
break;
case 5://删除员工信息
delete_worker_HMI(&msg);
send_fun(socketf,&msg);//发送
recv_fun(socketf,&msg);//接收
fla=flags(&msg);//0:未发送 1:发送成功
break;
default:
break;
}
}
END:
return 0;
}
代码实现:
员工管理系统