项目名称:员工管理系统
项目时间:3天
项目描述:
1)服务器负责管理所有员工表单(以数据库形式或文件形式都可),其他客户端可通过网络连接服务器来查询员工表单。
2)需要账号密码登陆,其中需要区分管理员账号还是普通用户账号。
3)管理员账号可以查看、修改员工表单,管理员要负责管理所有的普通用户。
4)普通用户只能查询修改与本人有关的相关信息,其他员工信息(出于保密原则)不得泄露。
5)有查询历史记录功能。
6)能同时处理多台客户端的请求功能。
- 【1】TCP通信的编程步骤
- 1.服务器:
- 1)创建套接字
- 2)绑定ip和端口号
- 3)监听
- 4)等待客户端连接
-
- int main()
- {
- //1.创建套接字
- int sockfd = socket();
- //2.初始化通信结构
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port = port;
- addr.sin_addr=addr;
- bind(sockfd, &addr);
- //3.监听
- listen();
- //4.连接
- while(1)
- {
- int connfd = accept();
- //5.循环数据收发
- while(1)
- {
- recv();
- send();
- }
- }
- close(sockfd);
- close(connfd);
- }
- 2.客户端:
- 1)创建套接字
- 2)连接服务器
-
- int main()
- {
- //1.创建套接字
- int sockfd = socket();
- //2.初始化通信结构
- struct sockaddr_in addr;
- addr.sin_family=AF_INET;
- addr.sin_port = port;
- addr.sin_addr=addr;
- //3.连接
- connect();
- //5.循环数据收发
- while(1)
- {
- send();
- recv();
- }
- }
-
- 【2】服务器模型
- 1.循环服务器
- 2.并发服务器
- 1)多线程
- 2)多进程
- 3)IO多路复用:
- a. select:
- 基本思想:
- 1. 先构造一张有关文件描述符的表(集合、数组); fd_set fd;
- 2. 将你关心的文件描述符加入到这个表中;FD_SET();
- 3. 然后调用一个函数。 select / poll
- 4. 当这些文件描述符中的一个或多个已准备好进行I/O操作的时候
- 该函数才返回(阻塞)。
- 5. 判断是哪一个或哪些文件描述符产生了事件(IO操作);
- 6. 做对应的逻辑处理;
- ****select函数返回之后,会自动将除了产生事件的文件描述符以外的位全部清空;
- 程序步骤:
- 1.把关心的文件描述符放入集合--FD_SET
- 2.监听集合中的文件描述符--select
- 3.依次判断哪个文件描述符有数据--FD_ISSET
- 4.依次处理有数据的文件描述符的数据
- 伪代码:
- fd_set fd;
- FD_SET(sockfd);
- while(1) {
- 设置监听读写文件描述符集合(FD_*);
- 调用select;
- select();
- 如果是监听套接字就绪,说明有新的连接请求
- if(sockfd)
- {
- 建立连接();
- int connfd = accept();
- 加入到监听文件描述符集合;
- FD_SET(connfd);
- }否则说明是一个已经连接过的描述符
- else
- {
- 进行操作(send或者recv);
- recv();
- send();
- }
- }
- select弊端:
- 1. 一个进程最多只能监听1024个文件描述符 (千级别)
- 2. select是一种轮询的机制;
- 3. 涉及到用户态和内核态的数据拷贝;
-
- b. poll
- 1. 优化文件描述符个数的限制;
- 2. poll是一种轮询的机制;
- 3. 涉及到用户态和内核态的数据拷贝;
- 函数接口:
- int poll(struct pollfd *fds, nfds_t nfds, int timeout);
- 参数:
- struct pollfd *fds
- 关心的文件描述符数组struct pollfd fds[N];
- nfds:个数
- timeout: 超市检测
- 毫秒级的:如果填1000,1秒
- 如果-1,阻塞
-
- 问题:
- 我想检测是键盘事件(标准输入 文件描述如为0 ),
- 还是鼠标事件(文件描述符是/dev/input/mouse1);
- 1. 创建一个结构体数组
- struct pollfd fds[2];
- 2. 将你关心的文件描述符加入到结构体成员中
- struct pollfd {
- int fd; // 关心的文件描述符;
- short events; // 关心的事件,读
- short revents; // 如果产生事件,则会自动填充该成员的值
- };
-
- // 键盘
- fds[0].fd = 0;
- fds[0].events = POLLIN;
-
- //鼠标
- fds[1].fd = mouse1_fd;
- fds[1].events = POLLIN;
-
- 3. 调用poll函数
- 如果返回表示有事件产生;
- poll(fds,2,1000)
- 4. 判断具体是哪个文件描述符产生了事件
- if(fds[0].revents == POLLIN)
- {
- ....
- }
-
- c. epoll
- 1. 没有文件描述符的限制
- 2. 异步IO,当有事件产生,文件描述符主动调用callback
- 3. 不用数据拷贝;
-
- 3个功能函数:
- #include
- int epoll_create(int size);//创建红黑树根节点
- //成功时返回epoll文件描述符,失败时返回-1
-
- //控制epoll属性
- int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
- epfd:epoll_create函数的返回句柄。
- op:表示动作类型。有三个宏 来表示:
- EPOLL_CTL_ADD:注册新的fd到epfd中
- EPOLL_CTL_MOD:修改已注册fd的监听事件
- EPOLL_CTL_DEL:从epfd中删除一个fd
- FD:需要监听的fd。
- event:告诉内核需要监听什么事件
- EPOLLIN:表示对应文件描述符可读
- EPOLLOUT:可写
- EPOLLPRI:有紧急数据可读;
- EPOLLERR:错误;
- EPOLLHUP:被挂断;
- EPOLLET:触发方式,电平触发;
- ET模式:表示状态的变化;
- //成功时返回0,失败时返回-1
-
- //等待事件到来
- int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
- 功能:等待事件的产生,类似于select嗲用
- epfd:句柄;
- events:用来从内核得到事件的集合;
- maxevents:表示每次能处理事件最大个数;
- timeout:超时时间,毫秒,0立即返回,-1阻塞
- //成功时返回发生事件的文件描述数,失败时返回-1
- 伪代码:
- 1.定义epoll事件,创建epoll的fd
- int epfd,epct,i;
- struct epoll_event event; //定义epoll 事件
- struct epoll_event events[20]; //定义epoll 事件集合
- epfd = epoll_create(1); // 创建epoll 的fd
- 2.填充事件
- event.data.fd = serverFd; //填充事件的fd
- event.events = EPOLLIN | EPOLLET; //填充 事件类型
- epoll_ctl(epfd,EPOLL_CTL_ADD,serverFd,&event); //把serverFd(监听FD)注册到epfd中
- 3.监听事件
- while(1){
- epct = epoll_wait(epfd,events,20,-1); // 等待事件到来,阻塞模式
- for(i=0;i
//根据epoll返回的值来查询事件 - if(events[i].data.fd == serverFd){ // 如果事件的fd是监听fd,调用accept处理
- clientFd = accept();
- //添加clientfd描述符
- epoll_ctl(epfd,EPOLL_CTL_ADD,clientFd,&event);
- }else {
- //如果不是serverFd,应是client数据事件,调用读数据
- read();
- }
- }
- }
-
- 【3】数据库函数接口
- 1.int sqlite3_open(char *path, sqlite3 **db);
- 功能:打开sqlite数据库
- 参数:
- path: 数据库文件路径
- db: 指向sqlite句柄的指针
- 返回值:成功返回0,失败返回错误码(非零值)
- 2.int sqlite3_close(sqlite3 *db);
- 功能:关闭sqlite数据库
- 返回值:成功返回0,失败返回错误码
-
- 3.int sqlite3_exec(sqlite3 *db, const char *sql,
- sqlite3_callback callback, void *, char **errmsg);
- 功能:执行SQL语句
- 参数:
- db:数据库句柄
- sql:SQL语句 ("create table stu .....;")
- callback:回调函数
- void * arg:
- 当使用查询命令的时候,callback和arg才有意义;
- select .....
- errmsg:错误信息指针的地址
- char *errmsg;
- &errmsg;
- 返回值:成功返回0,失败返回错误码
- int callback(void *para, int f_num, char **f_value, char **f_name);
- 功能:每找到一条记录自动执行一次回调函数
- 参数:
- para: 传递给回调函数的参数
- f_num: 记录中包含的字段数目(id name score)
- 相当于有多少列;
- f_value:包含每个字段值的指针数组
- f_name:包含每个字段名称的指针数组
- 返回值:成功返回0,失败返回-1
-
- 4.int sqlite3_get_table(sqlite3 *db, const char *sql,
- char ***resultp, int *nrow, int *ncolumn, char **errmsg);
- 功能:执行SQL操作
- 参数:
- db:数据库句柄
- sql:SQL语句
- resultp:用来指向sql执行结果的指针;实际上就是“指针数组指针”;
- nrow:满足条件的记录的数目,实际上就是有多少行数据;
- ncolumn:每条记录包含的字段数目,实际上就是有多少个字段(多少列);
- errmsg:错误信息指针的地址
- 返回值:成功返回0,失败返回错误码
-
- 练习:创建数据库stu.db,包含name、id、score字段,实现对数据库的增删改查。
-
- #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 "124.223.177.144"
- #define PORT "8888"
-
- char user_name[NAMELEN]; //姓名
- char user_passwd[PASSLEN]; //登陆密码
-
- char history[DATALEN+100];
-
-
-
-
- #endif
-
- int process_user_or_admin_login_request(int acceptfd, MSG *msg);
- int process_user_modify_request(int acceptfd, MSG *msg);
- int process_user_query_request(int acceptfd, MSG *msg);
- int process_admin_modify_request(int acceptfd, MSG *msg);
- int process_admin_adduser_request(int acceptfd, MSG *msg);
- int process_admin_deluser_request(int acceptfd, MSG *msg);
- int process_admin_query_request(int acceptfd, MSG *msg);
- int process_admin_history_request(int acceptfd, MSG *msg);
- int process_admin_list_request(int acceptfd, MSG *msg);
- int process_client_quit_request(int acceptfd, MSG *msg);
- int process_client_request(int acceptfd, MSG *msg);
- int process_recv_history_request(char *name,char *str);
-
- #include "common.h"
- #include "server.h"
-
- sqlite3 *db = NULL;
-
- //登录
- int process_user_or_admin_login_request(int acceptfd, MSG *msg)
- {
-
- //封装sql命令,表中查询用户名和密码-存在-登录成功-发送响应-失败-发送失败响应
- char sql[DATALEN] = {0};
- char *errmsg;
- char **result;
- int nrow, ncolumn;
-
- msg->info.usertype = msg->usertype;
- strcpy(msg->info.name, msg->username);
- strcpy(msg->info.passwd, msg->passwd);
-
- strcpy(user_name, msg->username);
- strcpy(user_passwd, msg->username);
-
- printf("usertype: %#x ,username: %s ,userpasswd: %s.\n", msg->info.usertype, msg->info.name, msg->info.passwd);
- sprintf(sql, "select * from usrinfo where usertype=%d and name='%s' and passwd='%s';", msg->info.usertype, msg->info.name, msg->info.passwd);
-
- if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
- {
- printf("---****----%s.\n", errmsg);
- }
- else
- {
- // printf("----nrow-----%d,ncolumn-----%d.\n",nrow,ncolumn);
- if (nrow == 0)
- {
- //查询到行为0
- strcpy(msg->recvmsg, "name or passwd failed.\n");
- send(acceptfd, msg, sizeof(MSG), 0);
- process_recv_history_request(msg->username, "longin error!");
- }
- else
- {
- strcpy(msg->recvmsg, "OK");
- send(acceptfd, msg, sizeof(MSG), 0);
- process_recv_history_request(msg->username, "longin success!");
- }
- }
- return 0;
- }
-
- //用户修改
- int process_user_modify_request(int acceptfd, MSG *msg)
- {
- char cmd[NAMELEN] = "";
- char *errmsg;
- char sql[DATALEN + 100] = "";
- int nrow = 0, ncolumn;
- char **result;
-
- switch (msg->flags)
- {
- case 1:
- sprintf(sql, "select * from usrinfo where taffon=%d;",msg->info.no);
-
- if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) == SQLITE_OK)
- {
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- sqlite3_free_table(result);
- return -1;
- }
- sprintf(sql, "UPDATE usrinfo SET taffon=%d WHERE name='%s' AND passwd='%s';", msg->info.no, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change taffon -> %d", msg->info.no);
- process_recv_history_request(msg->username, history);
-
- break;
- case 2:
- // sprintf(sql, "UPDATE usrinfo SET usertype=%d WHERE name='%s' AND passwd='%s';",msg->info.usertype,msg->username,msg->passwd);
- {
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- return -1;
- }
- break;
- case 3:
- sprintf(sql, "UPDATE usrinfo SET name='%s' WHERE name='%s' AND passwd='%s';", msg->info.name, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change name -> %s", msg->info.name);
- process_recv_history_request(msg->username, history);
-
- break;
- case 4:
- sprintf(sql, "UPDATE usrinfo SET passwd='%s' WHERE name='%s' AND passwd='%s';", msg->info.passwd, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change passwd -> %s", msg->info.passwd);
- process_recv_history_request(msg->username, history);
-
- break;
- case 5:
- sprintf(sql, "UPDATE usrinfo SET age=%d WHERE name='%s' AND passwd='%s';", msg->info.age, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change age -> %d", msg->info.age);
- process_recv_history_request(msg->username, history);
-
- break;
- case 6:
- sprintf(sql, "UPDATE usrinfo SET phone='%s' WHERE name='%s' AND passwd='%s';", msg->info.phone, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change phone -> %s", msg->info.phone);
- process_recv_history_request(msg->username, history);
-
- break;
- case 7:
- sprintf(sql, "UPDATE usrinfo SET addr='%s' WHERE name='%s' AND passwd='%s';", msg->info.addr, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change addr -> %s", msg->info.addr);
- process_recv_history_request(msg->username, history);
-
- break;
- case 8:
- sprintf(sql, "UPDATE usrinfo SET work='%s' WHERE name='%s' AND passwd='%s';", msg->info.work, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change work -> %s", msg->info.work);
- process_recv_history_request(msg->username, history);
-
- break;
- case 9:
- sprintf(sql, "UPDATE usrinfo SET date='%s' WHERE name='%s' AND passwd='%s';", msg->info.date, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change date -> %s", msg->info.date);
- process_recv_history_request(msg->username, history);
-
- break;
- case 10:
- sprintf(sql, "UPDATE usrinfo SET level=%d WHERE name='%s' AND passwd='%s';", msg->info.level, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change level -> %d", msg->info.level);
- process_recv_history_request(msg->username, history);
-
- break;
- case 11:
- sprintf(sql, "UPDATE usrinfo SET salary=%d WHERE name='%s' AND passwd='%s';", msg->info.salary, msg->username, msg->passwd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change salary -> %d", msg->info.salary);
- process_recv_history_request(msg->username, history);
-
- break;
- default:
- printf("enter error\n");
- return -1;
- }
-
- if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- {
- fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- return -1;
- }
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "ok");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- return 1;
- }
-
- //用户查找
- int process_user_query_request(int acceptfd, MSG *msg)
- {
- char sql[DATALEN + 50] = "";
- char **result = NULL;
- int row, column;
- char *errmsg = NULL;
-
- memset(history, 0, DATALEN);
- sprintf(history,"query self request");
- process_recv_history_request(msg->username, history);
-
- sprintf(sql, "select * from usrinfo where name='%s' and passwd='%s';", msg->username, msg->passwd);
-
- if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
- {
- goto end;
- }
- printf("查询结果成功\n");
-
- if (row == 0)
- {
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- sqlite3_free_table(result);
- return -1;
- }
-
- printf("row=%d column=%d\n", row, column);
-
- int i = 0;
-
- memset(msg->recvmsg, 0, DATALEN);
- for (i = 11; i < (row + 1) * column; i++)
- {
- switch (i % column)
- {
- case 0:
- msg->info.no = atoi(result[i]);
- break;
- case 1:
- msg->info.usertype = atoi(result[i]);
- break;
- case 2:
- strcpy(msg->info.name, result[i]);
- break;
- case 3:
- strcpy(msg->info.passwd, result[i]);
- break;
- case 4:
- msg->info.age = atoi(result[i]);
- break;
- case 5:
- strcpy(msg->info.phone, result[i]);
- break;
- case 6:
- strcpy(msg->info.addr, result[i]);
- break;
- case 7:
- strcpy(msg->info.work, result[i]);
- break;
- case 8:
- strcpy(msg->info.date, result[i]);
- break;
- case 9:
- msg->info.level = atoi(result[i]);
- break;
- case 10:
- msg->info.salary = atoi(result[i]);
- break;
- default:
- break;
- }
- if (i % column == (column - 1))
- {
- send(acceptfd, msg, sizeof(MSG), 0);
- memset(msg->recvmsg, 0, DATALEN);
- }
- }
- putchar(10);
-
- end:
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "end");
- send(acceptfd, msg, sizeof(MSG), 0);
-
- //释放查询到的结果
- sqlite3_free_table(result);
-
- return 0;
- }
-
- //管理修改
- int process_admin_modify_request(int acceptfd, MSG *msg)
- {
- char cmd[NAMELEN] = "";
- char *errmsg;
- char sql[DATALEN + 100] = "";
- int nrow = 0, ncolumn;
- char **result;
-
- sprintf(sql, "select * from usrinfo where name='%s';", msg->username);
-
- if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
- {
- printf("---select error----%s.\n", errmsg);
- }
-
- if (nrow == 0)
- {
- //如果此人信息不存在
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- return 0;
- }
-
- switch (msg->flags)
- {
- case 1:
- sprintf(sql, "UPDATE usrinfo SET taffon=%d WHERE name='%s';", msg->info.no, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s taffon -> %d",msg->username,msg->info.no);
- process_recv_history_request(msg->username, history);
-
- break;
- case 2:
- sprintf(sql, "UPDATE usrinfo SET usertype=%d WHERE name='%s';", msg->info.usertype, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s usertype -> %s",msg->username, msg->info.name);
- process_recv_history_request(msg->username, history);
-
- break;
- case 3:
- sprintf(sql, "UPDATE usrinfo SET name='%s' WHERE name='%s';", msg->info.name, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s name -> %s",msg->username, msg->info.name);
- process_recv_history_request(msg->username, history);
-
- break;
- case 4:
- sprintf(sql, "UPDATE usrinfo SET passwd='%s' WHERE name='%s';", msg->info.passwd, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s passwd -> %s",msg->username, msg->info.passwd);
- process_recv_history_request(msg->username, history);
-
- break;
- case 5:
- sprintf(sql, "UPDATE usrinfo SET age=%d WHERE name='%s';", msg->info.age, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s age -> %d", msg->username,msg->info.age);
- process_recv_history_request(msg->username, history);
-
- break;
- case 6:
- sprintf(sql, "UPDATE usrinfo SET phone='%s' WHERE name='%s';", msg->info.phone, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s phone -> %s",msg->username, msg->info.phone);
- process_recv_history_request(msg->username, history);
-
- break;
- case 7:
- sprintf(sql, "UPDATE usrinfo SET addr='%s' WHERE name='%s';", msg->info.addr, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s addr -> %s",msg->username, msg->info.addr);
- process_recv_history_request(msg->username, history);
-
- break;
- case 8:
- sprintf(sql, "UPDATE usrinfo SET work='%s' WHERE name='%s';", msg->info.work, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s work -> %s",msg->username, msg->info.work);
- process_recv_history_request(msg->username, history);
-
- break;
- case 9:
- sprintf(sql, "UPDATE usrinfo SET date='%s' WHERE name='%s';", msg->info.date, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s date -> %s",msg->username, msg->info.date);
- process_recv_history_request(msg->username, history);
-
- break;
- case 10:
- sprintf(sql, "UPDATE usrinfo SET level=%d WHERE name='%s';", msg->info.level, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s level -> %d",msg->username, msg->info.level);
- process_recv_history_request(msg->username, history);
-
- break;
- case 11:
- sprintf(sql, "UPDATE usrinfo SET salary=%d WHERE name='%s';", msg->info.salary, msg->username);
-
- memset(history, 0, DATALEN);
- sprintf(history,"change %s salary -> %d", msg->username,msg->info.salary);
- process_recv_history_request(msg->username, history);
-
- break;
- default:
- printf("enter error\n");
- return -1;
- }
-
- if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- {
- fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
- return -1;
- }
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "ok");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- return 1;
- }
-
- //管理添加
- int process_admin_adduser_request(int acceptfd, MSG *msg)
- {
- char cmd[NAMELEN] = "";
- char *errmsg;
- char sql[DATALEN + 400] = "";
- int nrow = 0, ncolumn;
- char **result;
-
-
- memset(history, 0, DATALEN);
- sprintf(history,"%s add %s",user_name,msg->info.name);
- process_recv_history_request(msg->username, history);
-
-
- sprintf(sql, "select * from usrinfo where staffno=%d;", msg->info.no);
-
- if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
- {
- printf("%d\n", __LINE__);
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- return -1;
- }
-
- if (nrow != 0)
- {
- //如果此人信息存在
- printf("%d\n", __LINE__);
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- return 0;
- }
-
- sprintf(sql, "INSERT INTO usrinfo VALUES (%d,%d,'%s','%s',%d,'%s','%s','%s','%s',%d,%d);", 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);
-
- if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- {
- fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
- return -1;
- }
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "ok");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- }
-
- //管理删除
- int process_admin_deluser_request(int acceptfd, MSG *msg)
- {
- char sql[DATALEN] = "";
- char *errmsg;
-
- memset(history, 0, DATALEN);
- sprintf(history,"%s del no -> %d",user_name,msg->info.no);
- process_recv_history_request(msg->username, history);
-
- sprintf(sql, "DELETE FROM usrinfo WHERE staffno=%d;", msg->info.no);
-
- if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- {
- fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "no");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- return -1;
- }
-
- memset(msg, 0, sizeof(MSG));
- strcpy(msg->recvmsg, "ok");
- if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
- {
- printf("Sending the account to the client error\n");
- return -1;
- }
- }
-
- //管理查找
- int process_admin_query_request(int acceptfd, MSG *msg)
- {
- char sql[DATALEN + 50] = "";
- char **result = NULL;
- int row, column;
- char *errmsg = NULL;
-
-
- memset(history, 0, DATALEN);
- sprintf(history,"find no-> %d",msg->info.no);
- process_recv_history_request(user_name, history);
-
-
- sprintf(sql, "select * from usrinfo where staffno=%d;", atoi(msg->recvmsg));
-
- if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
- {
- goto end;
- }
- printf("查询结果成功\n");
-
- if (row == 0)
- {
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- sqlite3_free_table(result);
- return -1;
- }
-
- printf("row=%d column=%d\n", row, column);
-
- int i = 0;
-
- memset(msg->recvmsg, 0, DATALEN);
- for (i = 11; i < (row + 1) * column; i++)
- {
- switch (i % column)
- {
- case 0:
- msg->info.no = atoi(result[i]);
- break;
- case 1:
- msg->info.usertype = atoi(result[i]);
- break;
- case 2:
- strcpy(msg->info.name, result[i]);
- break;
- case 3:
- strcpy(msg->info.passwd, result[i]);
- break;
- case 4:
- msg->info.age = atoi(result[i]);
- break;
- case 5:
- strcpy(msg->info.phone, result[i]);
- break;
- case 6:
- strcpy(msg->info.addr, result[i]);
- break;
- case 7:
- strcpy(msg->info.work, result[i]);
- break;
- case 8:
- strcpy(msg->info.date, result[i]);
- break;
- case 9:
- msg->info.level = atoi(result[i]);
- break;
- case 10:
- msg->info.salary = atoi(result[i]);
- break;
- default:
- break;
- }
- if (i % column == (column - 1))
- {
- send(acceptfd, msg, sizeof(MSG), 0);
- memset(msg->recvmsg, 0, DATALEN);
- }
- }
- putchar(10);
-
- end:
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "end");
- send(acceptfd, msg, sizeof(MSG), 0);
-
- //释放查询到的结果
- sqlite3_free_table(result);
-
- return 0;
- }
-
- //管理历史
- int process_admin_history_request(int acceptfd, MSG *msg)
- {
-
- memset(history, 0, DATALEN);
- sprintf(history,"(passwd:%s) -> cat history",user_passwd);
- process_recv_history_request(user_name, history);
-
-
- char sql[DATALEN] = "";
- char **result = NULL;
- int row, column;
- char *errmsg = NULL;
-
- sprintf(sql, "SELECT * FROM historyinfo;");
-
- if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
- {
- memset(msg->recvmsg, 0, DATALEN);
-
- msg->flags = 1;
-
- send(acceptfd, msg, sizeof(MSG), 0);
-
- //释放查询到的结果
- sqlite3_free_table(result);
-
- return -1;
-
- }
- printf("查询结果成功\n");
-
- if (row == 0)
- {
- memset(msg->recvmsg, 0, DATALEN);
- //strcpy(msg->recvmsg, "no");
-
- msg->flags = 2;
-
- send(acceptfd, msg, sizeof(MSG), 0);
- sqlite3_free_table(result);
-
- return -1;
- }
-
- printf("row=%d column=%d\n", row, column);
-
- int i = 0;
-
-
- for (i = 3; i < (row + 1) * column; i++)
- {
- strcat(msg->recvmsg, result[i]);
- strcat(msg->recvmsg, "\t");
- if (i % column == (column - 1))
- {
- strcat(msg->recvmsg, "\n");
- send(acceptfd, msg, sizeof(MSG), 0);
-
- recv(acceptfd, msg, sizeof(MSG), 0);
-
- printf("%s",msg->recvmsg);
-
- memset(msg->recvmsg, 0, DATALEN);
- }
- }
-
- memset(msg->recvmsg, 0, DATALEN);
-
- msg->flags = 1;
-
- send(acceptfd, msg, sizeof(MSG), 0);
-
- //释放查询到的结果
- sqlite3_free_table(result);
- }
-
- int process_recv_history_request(char *name, char *str)
- {
- char data[11] = ""; // 2022/10/29
- char timeb[9] = ""; // 02:18:00
-
- char his[50] = "";
- char sql[DATALEN] = "";
- char *errmsg = NULL;
-
- strcat(his, name);
- strcat(his, " : ");
- strcat(his, str);
-
- //转换成日历格式
- struct tm *p = NULL;
- long int q;
-
- q = time(NULL);
- p = localtime(&q);
-
- sprintf(data, "%04d-%02d-%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
- sprintf(timeb, "%02d:%02d:%02d", p->tm_hour, p->tm_min, p->tm_sec);
-
- sprintf(sql, "INSERT INTO historyinfo VALUES ('%s','%s','%s');", data, timeb, his);
-
- if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
- {
- fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
- return -1;
- }
- }
-
- //列表
- int process_admin_list_request(int acceptfd, MSG *msg)
- {
-
- memset(history, 0, DATALEN);
- sprintf(history,"(passwd:%s) -> cat list",user_passwd);
- process_recv_history_request(user_name, history);
-
-
-
- char sql[DATALEN] = "";
- char **result = NULL;
- int row, column;
- char *errmsg = NULL;
-
- sprintf(sql, "SELECT * FROM usrinfo;");
-
- if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
- {
- goto end;
- }
- printf("查询结果成功\n");
-
- if (row == 0)
- {
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "no");
- send(acceptfd, msg, sizeof(MSG), 0);
- sqlite3_free_table(result);
- return -1;
- }
-
- printf("row=%d column=%d\n", row, column);
-
- int i = 0;
-
- memset(msg->recvmsg, 0, DATALEN);
- for (i = 11; i < (row + 1) * column; i++)
- {
- switch (i % column)
- {
- case 0:
- msg->info.no = atoi(result[i]);
- break;
- case 1:
- msg->info.usertype = atoi(result[i]);
- break;
- case 2:
- strcpy(msg->info.name, result[i]);
- break;
- case 3:
- strcpy(msg->info.passwd, result[i]);
- break;
- case 4:
- msg->info.age = atoi(result[i]);
- break;
- case 5:
- strcpy(msg->info.phone, result[i]);
- break;
- case 6:
- strcpy(msg->info.addr, result[i]);
- break;
- case 7:
- strcpy(msg->info.work, result[i]);
- break;
- case 8:
- strcpy(msg->info.date, result[i]);
- break;
- case 9:
- msg->info.level = atoi(result[i]);
- break;
- case 10:
- msg->info.salary = atoi(result[i]);
- break;
- default:
- break;
- }
- if (i % column == (column - 1))
- {
- send(acceptfd, msg, sizeof(MSG), 0);
- recv(acceptfd, msg, sizeof(MSG), 0);
- memset(msg->recvmsg, 0, DATALEN);
- }
- }
- putchar(10);
-
- end:
- memset(msg->recvmsg, 0, DATALEN);
- strcpy(msg->recvmsg, "endd");
- send(acceptfd, msg, sizeof(MSG), 0);
-
- //释放查询到的结果
- sqlite3_free_table(result);
- }
-
- //客户端退出
- int process_client_quit_request(int acceptfd, MSG *msg)
- {
- printf("------------%s-----------%d.\n", __func__, __LINE__);
- }
-
- //处理客户端请求
- int process_client_request(int acceptfd, MSG *msg)
- {
- //请求的消息类型
- switch (msg->msgtype)
- {
- case USER_LOGIN:
- case ADMIN_LOGIN:
- process_user_or_admin_login_request(acceptfd, msg); //登录
- break;
- case USER_MODIFY:
- process_user_modify_request(acceptfd, msg); //用户修改
- break;
- case USER_QUERY:
- process_user_query_request(acceptfd, msg); //用户查找
- break;
- case ADMIN_MODIFY:
- process_admin_modify_request(acceptfd, msg); //管理修改
- break;
- case ADMIN_ADDUSER:
- process_admin_adduser_request(acceptfd, msg); //管理添加
- break;
- case ADMIN_DELUSER:
- process_admin_deluser_request(acceptfd, msg); //管理删除
- break;
- case ADMIN_QUERY:
- process_admin_query_request(acceptfd, msg); //管理查找
- break;
- case ADMIN_HISTORY:
- process_admin_history_request(acceptfd, msg); //管理历史
- break;
- case ADMIN_LIST:
- process_admin_list_request(acceptfd, msg); //列表
- break;
- case QUIT:
- process_client_quit_request(acceptfd, msg); //客户端退出
- break;
- default:
- break;
- }
- }
-
- int main(int argc, const char *argv[])
- {
- system("clear");
- //打开数据库
- if (sqlite3_open(STAFF_DATABASE, &db) != SQLITE_OK)
- {
- printf("%s.\n", sqlite3_errmsg(db));
- return -1;
- }
- printf("database open success\n");
-
-
- // socket->填充->绑定->监听->等待连接->数据交互->关闭
-
- //创建网络通信的套接字
- int socketfd = socket(AF_INET, SOCK_STREAM, 0);
- if (socketfd < 0)
- {
- printf("socket error\n");
- return -1;
- }
- printf("socket success\n");
-
- //允许端口快速重用
- int reuse = 1;
- if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
- {
- printf("setsockopt error\n");
- return -1;
- }
- printf("setsockopt success\n");
-
- //填充网络结构体
- //填充服务器网路信息结构体
- struct sockaddr_in sin;
- //填充为IPV4地址
- sin.sin_family = AF_INET;
- //填充服务器IP
- sin.sin_addr.s_addr = inet_addr(S_IP);
- //填充服务器端口号
- sin.sin_port = htons(atoi(PORT));
-
- //绑定网络套接字和网络结构体
- if (bind(socketfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- {
- printf("bind error\n");
- return -1;
- }
- printf("bind success\n");
-
- //监听套接字,将主动套接字转化为被动套接字
- if (listen(socketfd, 10) < 0)
- {
- printf("listen error\n");
- return -1;
- }
- printf("listen success\n");
-
- //通过select实现并发
- //客户端网络信息结构体
- struct sockaddr_in cin;
- socklen_t addrlen = sizeof(cin);
-
- //创建一个读集合
- fd_set readfds, tempfds;
-
- //将集合清空
- FD_ZERO(&readfds);
- FD_ZERO(&tempfds);
-
- //将sfd文件描述符添加到集合
- FD_SET(socketfd, &readfds);
-
- //最大文件描述符
- int maxfd = socketfd;
- //接收select返回值
- int select_res = 0;
- MSG msg;
- ssize_t recvbytes = 0;
- int acceptfd = -1;
- int i = 0;
-
- //定义一个数组,存储每次连接成功的客户端的信息
- struct sockaddr_in save_addr[1024 - 4];
-
- while (1)
- {
- tempfds = readfds;
- //>0, 三个集合中成功触发事件的文件描述符个数 =0超时 =-1失败;
- select_res = select(maxfd + 1, &tempfds, NULL, NULL, NULL);
- if (select_res < 0)
- {
- printf("select error\n");
- return -1;
- }
- else if (select_res == 0)
- {
- printf("select timeout\n");
- return -1;
- }
-
- for (i = 0; i <= maxfd; i++)
- {
- //判断0~maxfd这些文件描述符在不在集合中
- if (FD_ISSET(i, &tempfds) == 0)
- {
- continue;
- }
-
- //能运行到当前位置,则说明i所代表的文件描述符有事件产生
-
- //判断是否是集合里关注的事件
-
- if (socketfd == i)
- {
- printf("触发客户端连接事件:");
- fflush(stdout);
-
- //数据交互
- acceptfd = accept(socketfd, (struct sockaddr *)&cin, &addrlen);
- if (acceptfd == -1)
- {
- printf("acceptfd error\n");
- return -1;
- }
- //网络字节序的IP-->点分十进制 网络字节序的port--->本机字节序
- printf("[%s : %d] acceptfd = %d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), acceptfd);
-
- memset(history, 0, DATALEN);
- sprintf(history,"[%s : %d] acceptfd[%d]",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), acceptfd);
- process_recv_history_request("connect", history);
-
-
-
- //将cin存储到 save_addr数组对应的位置,
- // acceptfd==4,则存储到下标为0,acceptfd==5,存储到下标为1,acceptfd==n,则存储到下标为n-4的位置
- save_addr[acceptfd - 4] = cin;
-
- //将acceptfd添加到集合中
- FD_SET(acceptfd, &readfds);
-
- //更新maxfd
- maxfd = maxfd > acceptfd ? maxfd : acceptfd;
- }
- else
- {
- //客户端交互事件
- bzero(&msg, sizeof(MSG));
- recvbytes = recv(i, &msg, sizeof(MSG), 0);
- if (recvbytes == -1)
- {
- // <0 错误
- printf("recv error\n");
- continue;
- }
- else if (recvbytes == 0)
- {
- // ==0
- printf("[%s : %d] acceptfd = %d client off-line\n",
- inet_ntoa(save_addr[i - 4].sin_addr), ntohs(save_addr[i - 4].sin_port), i);
-
- memset(history, 0, DATALEN);
- sprintf(history,"[%s : %d] acceptfd = [%d]",inet_ntoa(save_addr[i - 4].sin_addr), ntohs(save_addr[i - 4].sin_port), i);
- process_recv_history_request("lost connect", history);
-
- //关闭文件描述符
- close(i);
-
- //将文件描述符从集合中剔除
- FD_CLR(i, &readfds);
-
- //更新maxfd
- for (int i = maxfd; i > 0; i--)
- {
- if (FD_ISSET(i, &readfds))
- {
- maxfd = i;
- break;
- }
- }
- printf("peer shutdown.\n");
- }
- else
- {
- //处理客户端请求
- process_client_request(i, &msg);
- }
- }
- }
- }
-
- close(socketfd);
-
- return 0;
- }
- void do_admin_query(int sockfd, MSG *msg);
- void do_admin_modification(int sockfd, MSG *msg);
- void do_admin_adduser(int sockfd, MSG *msg);
- void do_admin_deluser(int sockfd, MSG *msg);
- void do_admin_history(int sockfd, MSG *msg);
- void do_admin_list(int sockfd, MSG *msg);
- void admin_menu(int sockfd, MSG *msg);
- void do_user_query(int sockfd, MSG *msg);
- void do_user_modification(int sockfd, MSG *msg);
- void user_menu(int sockfd, MSG *msg);
- int admin_or_user_login(int sockfd, MSG *msg);
- int do_login(int socketfd);
-
- #include "common.h"
- #include "client.h"
-
- /**************************************
- *函数名: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 find ************\n");
- printf(" ************ 2 change ************\n");
- printf(" ************ 3 add ************\n");
- printf(" ************ 4 delete ************\n");
- printf(" ************ 5 list ************\n");
- printf(" ************ 6 clean ************\n");
- printf(" ************ 7 history ************\n");
- printf(" ************ 0 quit ************\n");
- printf("please enter your option:");
- 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 find ************\n");
- printf(" ************ 2 change ************\n");
- printf(" ************ 3 clean ************\n");
- printf(" ************ 0 quit ************\n");
- printf("please enter your option:");
- 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; // 1
- msg.usertype = ADMIN; // 0
- break;
- 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;
- //填充服务器IP
- sin.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;
- }
员工信息管理系统 测试