本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(1)

项目 - 员工信息管理系统

发布于2022-12-29 06:38     阅读(679)     评论(0)     点赞(23)     收藏(4)


员工管理系统工作流程图:

员工管理系统-服务器端流程图:

 员工管理系统-客户端流程图:

 

项目名称:员工管理系统

项目时间:3天

项目描述:

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

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

3)管理员账号可以查看、修改员工表单,管理员要负责管理所有的普通用户。

4)普通用户只能查询修改与本人有关的相关信息,其他员工信息(出于保密原则)不得泄露。

5)有查询历史记录功能。

6)能同时处理多台客户端的请求功能。

  1. 1】TCP通信的编程步骤
  2. 1.服务器:
  3. 1)创建套接字
  4. 2)绑定ip和端口号
  5. 3)监听
  6. 4)等待客户端连接
  7. int main()
  8. {
  9. //1.创建套接字
  10. int sockfd = socket();
  11. //2.初始化通信结构
  12. struct sockaddr_in addr;
  13. addr.sin_family=AF_INET;
  14. addr.sin_port = port;
  15. addr.sin_addr=addr;
  16. bind(sockfd, &addr);
  17. //3.监听
  18. listen();
  19. //4.连接
  20. while(1)
  21. {
  22. int connfd = accept();
  23. //5.循环数据收发
  24. while(1)
  25. {
  26. recv();
  27. send();
  28. }
  29. }
  30. close(sockfd);
  31. close(connfd);
  32. }
  33. 2.客户端:
  34. 1)创建套接字
  35. 2)连接服务器
  36. int main()
  37. {
  38. //1.创建套接字
  39. int sockfd = socket();
  40. //2.初始化通信结构
  41. struct sockaddr_in addr;
  42. addr.sin_family=AF_INET;
  43. addr.sin_port = port;
  44. addr.sin_addr=addr;
  45. //3.连接
  46. connect();
  47. //5.循环数据收发
  48. while(1)
  49. {
  50. send();
  51. recv();
  52. }
  53. }
  54. 2】服务器模型
  55. 1.循环服务器
  56. 2.并发服务器
  57. 1)多线程
  58. 2)多进程
  59. 3)IO多路复用:
  60. a. select
  61. 基本思想:
  62. 1. 先构造一张有关文件描述符的表(集合、数组); fd_set fd;
  63. 2. 将你关心的文件描述符加入到这个表中;FD_SET();
  64. 3. 然后调用一个函数。 select / poll
  65. 4. 当这些文件描述符中的一个或多个已准备好进行I/O操作的时候
  66. 该函数才返回(阻塞)。
  67. 5. 判断是哪一个或哪些文件描述符产生了事件(IO操作);
  68. 6. 做对应的逻辑处理;
  69. ****select函数返回之后,会自动将除了产生事件的文件描述符以外的位全部清空;
  70. 程序步骤:
  71. 1.把关心的文件描述符放入集合--FD_SET
  72. 2.监听集合中的文件描述符--select
  73. 3.依次判断哪个文件描述符有数据--FD_ISSET
  74. 4.依次处理有数据的文件描述符的数据
  75. 伪代码:
  76. fd_set fd;
  77. FD_SET(sockfd);
  78. while(1) {
  79. 设置监听读写文件描述符集合(FD_*);
  80. 调用select;
  81. select();
  82. 如果是监听套接字就绪,说明有新的连接请求
  83. if(sockfd)
  84. {
  85. 建立连接();
  86. int connfd = accept();
  87. 加入到监听文件描述符集合;
  88. FD_SET(connfd);
  89. }否则说明是一个已经连接过的描述符
  90. else
  91. {
  92. 进行操作(send或者recv);
  93. recv();
  94. send();
  95. }
  96. }
  97. select弊端:
  98. 1. 一个进程最多只能监听1024个文件描述符 (千级别)
  99. 2. select是一种轮询的机制;
  100. 3. 涉及到用户态和内核态的数据拷贝;
  101. b. poll
  102. 1. 优化文件描述符个数的限制;
  103. 2. poll是一种轮询的机制;
  104. 3. 涉及到用户态和内核态的数据拷贝;
  105. 函数接口:
  106. int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  107. 参数:
  108. struct pollfd *fds
  109. 关心的文件描述符数组struct pollfd fds[N];
  110. nfds:个数
  111. timeout: 超市检测
  112. 毫秒级的:如果填10001
  113. 如果-1,阻塞
  114. 问题:
  115. 我想检测是键盘事件(标准输入 文件描述如为0 ),
  116. 还是鼠标事件(文件描述符是/dev/input/mouse1);
  117. 1. 创建一个结构体数组
  118. struct pollfd fds[2];
  119. 2. 将你关心的文件描述符加入到结构体成员中
  120. struct pollfd {
  121. int fd; // 关心的文件描述符;
  122. short events; // 关心的事件,读
  123. short revents; // 如果产生事件,则会自动填充该成员的值
  124. };
  125. // 键盘
  126. fds[0].fd = 0;
  127. fds[0].events = POLLIN;
  128. //鼠标
  129. fds[1].fd = mouse1_fd;
  130. fds[1].events = POLLIN;
  131. 3. 调用poll函数
  132. 如果返回表示有事件产生;
  133. poll(fds,2,1000)
  134. 4. 判断具体是哪个文件描述符产生了事件
  135. if(fds[0].revents == POLLIN)
  136. {
  137. ....
  138. }
  139. c. epoll
  140. 1. 没有文件描述符的限制
  141. 2. 异步IO,当有事件产生,文件描述符主动调用callback
  142. 3. 不用数据拷贝;
  143. 3个功能函数:
  144. #include <sys/epoll.h>
  145. int epoll_create(int size);//创建红黑树根节点
  146. //成功时返回epoll文件描述符,失败时返回-1
  147. //控制epoll属性
  148. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  149. epfd:epoll_create函数的返回句柄。
  150. op:表示动作类型。有三个宏 来表示:
  151. EPOLL_CTL_ADD:注册新的fd到epfd中
  152. EPOLL_CTL_MOD:修改已注册fd的监听事件
  153. EPOLL_CTL_DEL:从epfd中删除一个fd
  154. FD:需要监听的fd。
  155. event:告诉内核需要监听什么事件
  156. EPOLLIN:表示对应文件描述符可读
  157. EPOLLOUT:可写
  158. EPOLLPRI:有紧急数据可读;
  159. EPOLLERR:错误;
  160. EPOLLHUP:被挂断;
  161. EPOLLET:触发方式,电平触发;
  162. ET模式:表示状态的变化;
  163. //成功时返回0,失败时返回-1
  164. //等待事件到来
  165. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  166. 功能:等待事件的产生,类似于select嗲用
  167. epfd:句柄;
  168. events:用来从内核得到事件的集合;
  169. maxevents:表示每次能处理事件最大个数;
  170. timeout:超时时间,毫秒,0立即返回,-1阻塞
  171. //成功时返回发生事件的文件描述数,失败时返回-1
  172. 伪代码:
  173. 1.定义epoll事件,创建epoll的fd
  174. int epfd,epct,i;
  175. struct epoll_event event; //定义epoll 事件
  176. struct epoll_event events[20]; //定义epoll 事件集合
  177. epfd = epoll_create(1); // 创建epoll 的fd
  178. 2.填充事件
  179. event.data.fd = serverFd; //填充事件的fd
  180. event.events = EPOLLIN | EPOLLET; //填充 事件类型
  181. epoll_ctl(epfd,EPOLL_CTL_ADD,serverFd,&event); //把serverFd(监听FD)注册到epfd中
  182. 3.监听事件
  183. while(1){
  184. epct = epoll_wait(epfd,events,20,-1); // 等待事件到来,阻塞模式
  185. for(i=0;i<epct;i++){ //根据epoll返回的值来查询事件
  186. if(events[i].data.fd == serverFd){ // 如果事件的fd是监听fd,调用accept处理
  187. clientFd = accept();
  188. //添加clientfd描述符
  189. epoll_ctl(epfd,EPOLL_CTL_ADD,clientFd,&event);
  190. }else {
  191. //如果不是serverFd,应是client数据事件,调用读数据
  192. read();
  193. }
  194. }
  195. }
  196. 3】数据库函数接口
  197. 1.int sqlite3_open(char *path, sqlite3 **db);
  198. 功能:打开sqlite数据库
  199. 参数:
  200. path: 数据库文件路径
  201. db: 指向sqlite句柄的指针
  202. 返回值:成功返回0,失败返回错误码(非零值)
  203. 2.int sqlite3_close(sqlite3 *db);
  204. 功能:关闭sqlite数据库
  205. 返回值:成功返回0,失败返回错误码
  206. 3.int sqlite3_exec(sqlite3 *db, const char *sql,
  207. sqlite3_callback callback, void *, char **errmsg);
  208. 功能:执行SQL语句
  209. 参数:
  210. db:数据库句柄
  211. sql:SQL语句 ("create table stu .....;")
  212. callback:回调函数
  213. void * arg:
  214. 当使用查询命令的时候,callback和arg才有意义;
  215. select .....
  216. errmsg:错误信息指针的地址
  217. char *errmsg;
  218. &errmsg;
  219. 返回值:成功返回0,失败返回错误码
  220. int callback(void *para, int f_num, char **f_value, char **f_name);
  221. 功能:每找到一条记录自动执行一次回调函数
  222. 参数:
  223. para: 传递给回调函数的参数
  224. f_num: 记录中包含的字段数目(id name score)
  225. 相当于有多少列;
  226. f_value:包含每个字段值的指针数组
  227. f_name:包含每个字段名称的指针数组
  228. 返回值:成功返回0,失败返回-1
  229. 4.int sqlite3_get_table(sqlite3 *db, const char *sql,
  230. char ***resultp, int *nrow, int *ncolumn, char **errmsg);
  231. 功能:执行SQL操作
  232. 参数:
  233. db:数据库句柄
  234. sql:SQL语句
  235. resultp:用来指向sql执行结果的指针;实际上就是“指针数组指针”;
  236. nrow:满足条件的记录的数目,实际上就是有多少行数据;
  237. ncolumn:每条记录包含的字段数目,实际上就是有多少个字段(多少列);
  238. errmsg:错误信息指针的地址
  239. 返回值:成功返回0,失败返回错误码
  240. 练习:创建数据库stu.db,包含name、id、score字段,实现对数据库的增删改查。

代码实现:

服务器端(common.h文件,客户端服务器通用):

  1. #ifndef _COMMON_H_
  2. #define _COMMON_H_
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/socket.h>
  6. #include <sys/types.h>
  7. #include <arpa/inet.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <string.h>
  11. #include <sqlite3.h>
  12. #include <sys/wait.h>
  13. #include <signal.h>
  14. #include <time.h>
  15. #include <pthread.h>
  16. #include <sys/stat.h>
  17. #include <sqlite3.h>
  18. #include <netinet/in.h>
  19. #include <sys/select.h>
  20. #include <pthread.h>
  21. #define STAFF_DATABASE "staff_manage_system.db"
  22. #define USER_LOGIN 0x00000000 // login 登陆 0x00000001
  23. #define USER_MODIFY 0x00000001 // user-modification 修改
  24. #define USER_QUERY 0x00000002 // user-query 查询
  25. #define ADMIN_LOGIN 0x10000000 // login 登陆 0x00000001
  26. #define ADMIN_MODIFY 0x10000001 // admin_modification 修改
  27. #define ADMIN_ADDUSER 0x10000002 // admin_adduser 添加
  28. #define ADMIN_DELUSER 0x10000004 // admin_deluser 删除
  29. #define ADMIN_QUERY 0x10000008 //hitory_query 查找
  30. #define ADMIN_HISTORY 0x10000010 //hitory_history 历史
  31. #define ADMIN_LIST 0x10000011 //列表
  32. #define QUIT 0x11111111
  33. #define ADMIN 0 //管理员
  34. #define USER 1 //用户
  35. #define PASSLEN 8
  36. #define NAMELEN 16
  37. #define DATALEN 128
  38. /*员工基本信息*/
  39. typedef struct staff_info
  40. {
  41. int no; //员工编号
  42. int usertype; //ADMIN 1 USER 2
  43. char name[NAMELEN]; //姓名
  44. char passwd[PASSLEN]; //密码
  45. int age; // 年龄
  46. char phone[NAMELEN]; //电话
  47. char addr[DATALEN]; // 地址
  48. char work[DATALEN]; //职位
  49. char date[DATALEN]; //入职年月
  50. int level; // 等级
  51. int salary; // 工资
  52. }staff_info_t;
  53. /*定义双方通信的结构体信息*/
  54. typedef struct
  55. {
  56. int msgtype; //请求的消息类型
  57. int usertype; //ADMIN 1 USER 2
  58. char username[NAMELEN]; //姓名
  59. char passwd[PASSLEN]; //登陆密码
  60. char recvmsg[DATALEN]; //通信的消息
  61. int flags; //标志位
  62. staff_info_t info; //员工信息
  63. }MSG;
  64. #define S_IP "10.0.12.9"
  65. #define IP "124.223.177.144"
  66. #define PORT "8888"
  67. char user_name[NAMELEN]; //姓名
  68. char user_passwd[PASSLEN]; //登陆密码
  69. char history[DATALEN+100];
  70. #endif

服务器端(server.h文件):

  1. int process_user_or_admin_login_request(int acceptfd, MSG *msg);
  2. int process_user_modify_request(int acceptfd, MSG *msg);
  3. int process_user_query_request(int acceptfd, MSG *msg);
  4. int process_admin_modify_request(int acceptfd, MSG *msg);
  5. int process_admin_adduser_request(int acceptfd, MSG *msg);
  6. int process_admin_deluser_request(int acceptfd, MSG *msg);
  7. int process_admin_query_request(int acceptfd, MSG *msg);
  8. int process_admin_history_request(int acceptfd, MSG *msg);
  9. int process_admin_list_request(int acceptfd, MSG *msg);
  10. int process_client_quit_request(int acceptfd, MSG *msg);
  11. int process_client_request(int acceptfd, MSG *msg);
  12. int process_recv_history_request(char *name,char *str);

服务器端(server.c文件):

  1. #include "common.h"
  2. #include "server.h"
  3. sqlite3 *db = NULL;
  4. //登录
  5. int process_user_or_admin_login_request(int acceptfd, MSG *msg)
  6. {
  7. //封装sql命令,表中查询用户名和密码-存在-登录成功-发送响应-失败-发送失败响应
  8. char sql[DATALEN] = {0};
  9. char *errmsg;
  10. char **result;
  11. int nrow, ncolumn;
  12. msg->info.usertype = msg->usertype;
  13. strcpy(msg->info.name, msg->username);
  14. strcpy(msg->info.passwd, msg->passwd);
  15. strcpy(user_name, msg->username);
  16. strcpy(user_passwd, msg->username);
  17. printf("usertype: %#x ,username: %s ,userpasswd: %s.\n", msg->info.usertype, msg->info.name, msg->info.passwd);
  18. sprintf(sql, "select * from usrinfo where usertype=%d and name='%s' and passwd='%s';", msg->info.usertype, msg->info.name, msg->info.passwd);
  19. if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
  20. {
  21. printf("---****----%s.\n", errmsg);
  22. }
  23. else
  24. {
  25. // printf("----nrow-----%d,ncolumn-----%d.\n",nrow,ncolumn);
  26. if (nrow == 0)
  27. {
  28. //查询到行为0
  29. strcpy(msg->recvmsg, "name or passwd failed.\n");
  30. send(acceptfd, msg, sizeof(MSG), 0);
  31. process_recv_history_request(msg->username, "longin error!");
  32. }
  33. else
  34. {
  35. strcpy(msg->recvmsg, "OK");
  36. send(acceptfd, msg, sizeof(MSG), 0);
  37. process_recv_history_request(msg->username, "longin success!");
  38. }
  39. }
  40. return 0;
  41. }
  42. //用户修改
  43. int process_user_modify_request(int acceptfd, MSG *msg)
  44. {
  45. char cmd[NAMELEN] = "";
  46. char *errmsg;
  47. char sql[DATALEN + 100] = "";
  48. int nrow = 0, ncolumn;
  49. char **result;
  50. switch (msg->flags)
  51. {
  52. case 1:
  53. sprintf(sql, "select * from usrinfo where taffon=%d;",msg->info.no);
  54. if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) == SQLITE_OK)
  55. {
  56. memset(msg->recvmsg, 0, DATALEN);
  57. strcpy(msg->recvmsg, "no");
  58. send(acceptfd, msg, sizeof(MSG), 0);
  59. sqlite3_free_table(result);
  60. return -1;
  61. }
  62. sprintf(sql, "UPDATE usrinfo SET taffon=%d WHERE name='%s' AND passwd='%s';", msg->info.no, msg->username, msg->passwd);
  63. memset(history, 0, DATALEN);
  64. sprintf(history,"change taffon -> %d", msg->info.no);
  65. process_recv_history_request(msg->username, history);
  66. break;
  67. case 2:
  68. // sprintf(sql, "UPDATE usrinfo SET usertype=%d WHERE name='%s' AND passwd='%s';",msg->info.usertype,msg->username,msg->passwd);
  69. {
  70. memset(msg, 0, sizeof(MSG));
  71. strcpy(msg->recvmsg, "no");
  72. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  73. {
  74. printf("Sending the account to the client error\n");
  75. return -1;
  76. }
  77. return -1;
  78. }
  79. break;
  80. case 3:
  81. sprintf(sql, "UPDATE usrinfo SET name='%s' WHERE name='%s' AND passwd='%s';", msg->info.name, msg->username, msg->passwd);
  82. memset(history, 0, DATALEN);
  83. sprintf(history,"change name -> %s", msg->info.name);
  84. process_recv_history_request(msg->username, history);
  85. break;
  86. case 4:
  87. sprintf(sql, "UPDATE usrinfo SET passwd='%s' WHERE name='%s' AND passwd='%s';", msg->info.passwd, msg->username, msg->passwd);
  88. memset(history, 0, DATALEN);
  89. sprintf(history,"change passwd -> %s", msg->info.passwd);
  90. process_recv_history_request(msg->username, history);
  91. break;
  92. case 5:
  93. sprintf(sql, "UPDATE usrinfo SET age=%d WHERE name='%s' AND passwd='%s';", msg->info.age, msg->username, msg->passwd);
  94. memset(history, 0, DATALEN);
  95. sprintf(history,"change age -> %d", msg->info.age);
  96. process_recv_history_request(msg->username, history);
  97. break;
  98. case 6:
  99. sprintf(sql, "UPDATE usrinfo SET phone='%s' WHERE name='%s' AND passwd='%s';", msg->info.phone, msg->username, msg->passwd);
  100. memset(history, 0, DATALEN);
  101. sprintf(history,"change phone -> %s", msg->info.phone);
  102. process_recv_history_request(msg->username, history);
  103. break;
  104. case 7:
  105. sprintf(sql, "UPDATE usrinfo SET addr='%s' WHERE name='%s' AND passwd='%s';", msg->info.addr, msg->username, msg->passwd);
  106. memset(history, 0, DATALEN);
  107. sprintf(history,"change addr -> %s", msg->info.addr);
  108. process_recv_history_request(msg->username, history);
  109. break;
  110. case 8:
  111. sprintf(sql, "UPDATE usrinfo SET work='%s' WHERE name='%s' AND passwd='%s';", msg->info.work, msg->username, msg->passwd);
  112. memset(history, 0, DATALEN);
  113. sprintf(history,"change work -> %s", msg->info.work);
  114. process_recv_history_request(msg->username, history);
  115. break;
  116. case 9:
  117. sprintf(sql, "UPDATE usrinfo SET date='%s' WHERE name='%s' AND passwd='%s';", msg->info.date, msg->username, msg->passwd);
  118. memset(history, 0, DATALEN);
  119. sprintf(history,"change date -> %s", msg->info.date);
  120. process_recv_history_request(msg->username, history);
  121. break;
  122. case 10:
  123. sprintf(sql, "UPDATE usrinfo SET level=%d WHERE name='%s' AND passwd='%s';", msg->info.level, msg->username, msg->passwd);
  124. memset(history, 0, DATALEN);
  125. sprintf(history,"change level -> %d", msg->info.level);
  126. process_recv_history_request(msg->username, history);
  127. break;
  128. case 11:
  129. sprintf(sql, "UPDATE usrinfo SET salary=%d WHERE name='%s' AND passwd='%s';", msg->info.salary, msg->username, msg->passwd);
  130. memset(history, 0, DATALEN);
  131. sprintf(history,"change salary -> %d", msg->info.salary);
  132. process_recv_history_request(msg->username, history);
  133. break;
  134. default:
  135. printf("enter error\n");
  136. return -1;
  137. }
  138. if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
  139. {
  140. fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
  141. memset(msg, 0, sizeof(MSG));
  142. strcpy(msg->recvmsg, "no");
  143. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  144. {
  145. printf("Sending the account to the client error\n");
  146. return -1;
  147. }
  148. return -1;
  149. }
  150. memset(msg, 0, sizeof(MSG));
  151. strcpy(msg->recvmsg, "ok");
  152. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  153. {
  154. printf("Sending the account to the client error\n");
  155. return -1;
  156. }
  157. return 1;
  158. }
  159. //用户查找
  160. int process_user_query_request(int acceptfd, MSG *msg)
  161. {
  162. char sql[DATALEN + 50] = "";
  163. char **result = NULL;
  164. int row, column;
  165. char *errmsg = NULL;
  166. memset(history, 0, DATALEN);
  167. sprintf(history,"query self request");
  168. process_recv_history_request(msg->username, history);
  169. sprintf(sql, "select * from usrinfo where name='%s' and passwd='%s';", msg->username, msg->passwd);
  170. if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
  171. {
  172. goto end;
  173. }
  174. printf("查询结果成功\n");
  175. if (row == 0)
  176. {
  177. memset(msg->recvmsg, 0, DATALEN);
  178. strcpy(msg->recvmsg, "no");
  179. send(acceptfd, msg, sizeof(MSG), 0);
  180. sqlite3_free_table(result);
  181. return -1;
  182. }
  183. printf("row=%d column=%d\n", row, column);
  184. int i = 0;
  185. memset(msg->recvmsg, 0, DATALEN);
  186. for (i = 11; i < (row + 1) * column; i++)
  187. {
  188. switch (i % column)
  189. {
  190. case 0:
  191. msg->info.no = atoi(result[i]);
  192. break;
  193. case 1:
  194. msg->info.usertype = atoi(result[i]);
  195. break;
  196. case 2:
  197. strcpy(msg->info.name, result[i]);
  198. break;
  199. case 3:
  200. strcpy(msg->info.passwd, result[i]);
  201. break;
  202. case 4:
  203. msg->info.age = atoi(result[i]);
  204. break;
  205. case 5:
  206. strcpy(msg->info.phone, result[i]);
  207. break;
  208. case 6:
  209. strcpy(msg->info.addr, result[i]);
  210. break;
  211. case 7:
  212. strcpy(msg->info.work, result[i]);
  213. break;
  214. case 8:
  215. strcpy(msg->info.date, result[i]);
  216. break;
  217. case 9:
  218. msg->info.level = atoi(result[i]);
  219. break;
  220. case 10:
  221. msg->info.salary = atoi(result[i]);
  222. break;
  223. default:
  224. break;
  225. }
  226. if (i % column == (column - 1))
  227. {
  228. send(acceptfd, msg, sizeof(MSG), 0);
  229. memset(msg->recvmsg, 0, DATALEN);
  230. }
  231. }
  232. putchar(10);
  233. end:
  234. memset(msg->recvmsg, 0, DATALEN);
  235. strcpy(msg->recvmsg, "end");
  236. send(acceptfd, msg, sizeof(MSG), 0);
  237. //释放查询到的结果
  238. sqlite3_free_table(result);
  239. return 0;
  240. }
  241. //管理修改
  242. int process_admin_modify_request(int acceptfd, MSG *msg)
  243. {
  244. char cmd[NAMELEN] = "";
  245. char *errmsg;
  246. char sql[DATALEN + 100] = "";
  247. int nrow = 0, ncolumn;
  248. char **result;
  249. sprintf(sql, "select * from usrinfo where name='%s';", msg->username);
  250. if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
  251. {
  252. printf("---select error----%s.\n", errmsg);
  253. }
  254. if (nrow == 0)
  255. {
  256. //如果此人信息不存在
  257. memset(msg, 0, sizeof(MSG));
  258. strcpy(msg->recvmsg, "no");
  259. send(acceptfd, msg, sizeof(MSG), 0);
  260. return 0;
  261. }
  262. switch (msg->flags)
  263. {
  264. case 1:
  265. sprintf(sql, "UPDATE usrinfo SET taffon=%d WHERE name='%s';", msg->info.no, msg->username);
  266. memset(history, 0, DATALEN);
  267. sprintf(history,"change %s taffon -> %d",msg->username,msg->info.no);
  268. process_recv_history_request(msg->username, history);
  269. break;
  270. case 2:
  271. sprintf(sql, "UPDATE usrinfo SET usertype=%d WHERE name='%s';", msg->info.usertype, msg->username);
  272. memset(history, 0, DATALEN);
  273. sprintf(history,"change %s usertype -> %s",msg->username, msg->info.name);
  274. process_recv_history_request(msg->username, history);
  275. break;
  276. case 3:
  277. sprintf(sql, "UPDATE usrinfo SET name='%s' WHERE name='%s';", msg->info.name, msg->username);
  278. memset(history, 0, DATALEN);
  279. sprintf(history,"change %s name -> %s",msg->username, msg->info.name);
  280. process_recv_history_request(msg->username, history);
  281. break;
  282. case 4:
  283. sprintf(sql, "UPDATE usrinfo SET passwd='%s' WHERE name='%s';", msg->info.passwd, msg->username);
  284. memset(history, 0, DATALEN);
  285. sprintf(history,"change %s passwd -> %s",msg->username, msg->info.passwd);
  286. process_recv_history_request(msg->username, history);
  287. break;
  288. case 5:
  289. sprintf(sql, "UPDATE usrinfo SET age=%d WHERE name='%s';", msg->info.age, msg->username);
  290. memset(history, 0, DATALEN);
  291. sprintf(history,"change %s age -> %d", msg->username,msg->info.age);
  292. process_recv_history_request(msg->username, history);
  293. break;
  294. case 6:
  295. sprintf(sql, "UPDATE usrinfo SET phone='%s' WHERE name='%s';", msg->info.phone, msg->username);
  296. memset(history, 0, DATALEN);
  297. sprintf(history,"change %s phone -> %s",msg->username, msg->info.phone);
  298. process_recv_history_request(msg->username, history);
  299. break;
  300. case 7:
  301. sprintf(sql, "UPDATE usrinfo SET addr='%s' WHERE name='%s';", msg->info.addr, msg->username);
  302. memset(history, 0, DATALEN);
  303. sprintf(history,"change %s addr -> %s",msg->username, msg->info.addr);
  304. process_recv_history_request(msg->username, history);
  305. break;
  306. case 8:
  307. sprintf(sql, "UPDATE usrinfo SET work='%s' WHERE name='%s';", msg->info.work, msg->username);
  308. memset(history, 0, DATALEN);
  309. sprintf(history,"change %s work -> %s",msg->username, msg->info.work);
  310. process_recv_history_request(msg->username, history);
  311. break;
  312. case 9:
  313. sprintf(sql, "UPDATE usrinfo SET date='%s' WHERE name='%s';", msg->info.date, msg->username);
  314. memset(history, 0, DATALEN);
  315. sprintf(history,"change %s date -> %s",msg->username, msg->info.date);
  316. process_recv_history_request(msg->username, history);
  317. break;
  318. case 10:
  319. sprintf(sql, "UPDATE usrinfo SET level=%d WHERE name='%s';", msg->info.level, msg->username);
  320. memset(history, 0, DATALEN);
  321. sprintf(history,"change %s level -> %d",msg->username, msg->info.level);
  322. process_recv_history_request(msg->username, history);
  323. break;
  324. case 11:
  325. sprintf(sql, "UPDATE usrinfo SET salary=%d WHERE name='%s';", msg->info.salary, msg->username);
  326. memset(history, 0, DATALEN);
  327. sprintf(history,"change %s salary -> %d", msg->username,msg->info.salary);
  328. process_recv_history_request(msg->username, history);
  329. break;
  330. default:
  331. printf("enter error\n");
  332. return -1;
  333. }
  334. if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
  335. {
  336. fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
  337. return -1;
  338. }
  339. memset(msg, 0, sizeof(MSG));
  340. strcpy(msg->recvmsg, "ok");
  341. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  342. {
  343. printf("Sending the account to the client error\n");
  344. return -1;
  345. }
  346. return 1;
  347. }
  348. //管理添加
  349. int process_admin_adduser_request(int acceptfd, MSG *msg)
  350. {
  351. char cmd[NAMELEN] = "";
  352. char *errmsg;
  353. char sql[DATALEN + 400] = "";
  354. int nrow = 0, ncolumn;
  355. char **result;
  356. memset(history, 0, DATALEN);
  357. sprintf(history,"%s add %s",user_name,msg->info.name);
  358. process_recv_history_request(msg->username, history);
  359. sprintf(sql, "select * from usrinfo where staffno=%d;", msg->info.no);
  360. if (sqlite3_get_table(db, sql, &result, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
  361. {
  362. printf("%d\n", __LINE__);
  363. memset(msg, 0, sizeof(MSG));
  364. strcpy(msg->recvmsg, "no");
  365. send(acceptfd, msg, sizeof(MSG), 0);
  366. return -1;
  367. }
  368. if (nrow != 0)
  369. {
  370. //如果此人信息存在
  371. printf("%d\n", __LINE__);
  372. memset(msg, 0, sizeof(MSG));
  373. strcpy(msg->recvmsg, "no");
  374. send(acceptfd, msg, sizeof(MSG), 0);
  375. return 0;
  376. }
  377. 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);
  378. if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
  379. {
  380. fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
  381. return -1;
  382. }
  383. memset(msg, 0, sizeof(MSG));
  384. strcpy(msg->recvmsg, "ok");
  385. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  386. {
  387. printf("Sending the account to the client error\n");
  388. return -1;
  389. }
  390. }
  391. //管理删除
  392. int process_admin_deluser_request(int acceptfd, MSG *msg)
  393. {
  394. char sql[DATALEN] = "";
  395. char *errmsg;
  396. memset(history, 0, DATALEN);
  397. sprintf(history,"%s del no -> %d",user_name,msg->info.no);
  398. process_recv_history_request(msg->username, history);
  399. sprintf(sql, "DELETE FROM usrinfo WHERE staffno=%d;", msg->info.no);
  400. if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
  401. {
  402. fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
  403. memset(msg, 0, sizeof(MSG));
  404. strcpy(msg->recvmsg, "no");
  405. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  406. {
  407. printf("Sending the account to the client error\n");
  408. return -1;
  409. }
  410. return -1;
  411. }
  412. memset(msg, 0, sizeof(MSG));
  413. strcpy(msg->recvmsg, "ok");
  414. if (send(acceptfd, msg, sizeof(MSG), 0) < 0)
  415. {
  416. printf("Sending the account to the client error\n");
  417. return -1;
  418. }
  419. }
  420. //管理查找
  421. int process_admin_query_request(int acceptfd, MSG *msg)
  422. {
  423. char sql[DATALEN + 50] = "";
  424. char **result = NULL;
  425. int row, column;
  426. char *errmsg = NULL;
  427. memset(history, 0, DATALEN);
  428. sprintf(history,"find no-> %d",msg->info.no);
  429. process_recv_history_request(user_name, history);
  430. sprintf(sql, "select * from usrinfo where staffno=%d;", atoi(msg->recvmsg));
  431. if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
  432. {
  433. goto end;
  434. }
  435. printf("查询结果成功\n");
  436. if (row == 0)
  437. {
  438. memset(msg->recvmsg, 0, DATALEN);
  439. strcpy(msg->recvmsg, "no");
  440. send(acceptfd, msg, sizeof(MSG), 0);
  441. sqlite3_free_table(result);
  442. return -1;
  443. }
  444. printf("row=%d column=%d\n", row, column);
  445. int i = 0;
  446. memset(msg->recvmsg, 0, DATALEN);
  447. for (i = 11; i < (row + 1) * column; i++)
  448. {
  449. switch (i % column)
  450. {
  451. case 0:
  452. msg->info.no = atoi(result[i]);
  453. break;
  454. case 1:
  455. msg->info.usertype = atoi(result[i]);
  456. break;
  457. case 2:
  458. strcpy(msg->info.name, result[i]);
  459. break;
  460. case 3:
  461. strcpy(msg->info.passwd, result[i]);
  462. break;
  463. case 4:
  464. msg->info.age = atoi(result[i]);
  465. break;
  466. case 5:
  467. strcpy(msg->info.phone, result[i]);
  468. break;
  469. case 6:
  470. strcpy(msg->info.addr, result[i]);
  471. break;
  472. case 7:
  473. strcpy(msg->info.work, result[i]);
  474. break;
  475. case 8:
  476. strcpy(msg->info.date, result[i]);
  477. break;
  478. case 9:
  479. msg->info.level = atoi(result[i]);
  480. break;
  481. case 10:
  482. msg->info.salary = atoi(result[i]);
  483. break;
  484. default:
  485. break;
  486. }
  487. if (i % column == (column - 1))
  488. {
  489. send(acceptfd, msg, sizeof(MSG), 0);
  490. memset(msg->recvmsg, 0, DATALEN);
  491. }
  492. }
  493. putchar(10);
  494. end:
  495. memset(msg->recvmsg, 0, DATALEN);
  496. strcpy(msg->recvmsg, "end");
  497. send(acceptfd, msg, sizeof(MSG), 0);
  498. //释放查询到的结果
  499. sqlite3_free_table(result);
  500. return 0;
  501. }
  502. //管理历史
  503. int process_admin_history_request(int acceptfd, MSG *msg)
  504. {
  505. memset(history, 0, DATALEN);
  506. sprintf(history,"(passwd:%s) -> cat history",user_passwd);
  507. process_recv_history_request(user_name, history);
  508. char sql[DATALEN] = "";
  509. char **result = NULL;
  510. int row, column;
  511. char *errmsg = NULL;
  512. sprintf(sql, "SELECT * FROM historyinfo;");
  513. if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
  514. {
  515. memset(msg->recvmsg, 0, DATALEN);
  516. msg->flags = 1;
  517. send(acceptfd, msg, sizeof(MSG), 0);
  518. //释放查询到的结果
  519. sqlite3_free_table(result);
  520. return -1;
  521. }
  522. printf("查询结果成功\n");
  523. if (row == 0)
  524. {
  525. memset(msg->recvmsg, 0, DATALEN);
  526. //strcpy(msg->recvmsg, "no");
  527. msg->flags = 2;
  528. send(acceptfd, msg, sizeof(MSG), 0);
  529. sqlite3_free_table(result);
  530. return -1;
  531. }
  532. printf("row=%d column=%d\n", row, column);
  533. int i = 0;
  534. for (i = 3; i < (row + 1) * column; i++)
  535. {
  536. strcat(msg->recvmsg, result[i]);
  537. strcat(msg->recvmsg, "\t");
  538. if (i % column == (column - 1))
  539. {
  540. strcat(msg->recvmsg, "\n");
  541. send(acceptfd, msg, sizeof(MSG), 0);
  542. recv(acceptfd, msg, sizeof(MSG), 0);
  543. printf("%s",msg->recvmsg);
  544. memset(msg->recvmsg, 0, DATALEN);
  545. }
  546. }
  547. memset(msg->recvmsg, 0, DATALEN);
  548. msg->flags = 1;
  549. send(acceptfd, msg, sizeof(MSG), 0);
  550. //释放查询到的结果
  551. sqlite3_free_table(result);
  552. }
  553. int process_recv_history_request(char *name, char *str)
  554. {
  555. char data[11] = ""; // 2022/10/29
  556. char timeb[9] = ""; // 02:18:00
  557. char his[50] = "";
  558. char sql[DATALEN] = "";
  559. char *errmsg = NULL;
  560. strcat(his, name);
  561. strcat(his, " : ");
  562. strcat(his, str);
  563. //转换成日历格式
  564. struct tm *p = NULL;
  565. long int q;
  566. q = time(NULL);
  567. p = localtime(&q);
  568. sprintf(data, "%04d-%02d-%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
  569. sprintf(timeb, "%02d:%02d:%02d", p->tm_hour, p->tm_min, p->tm_sec);
  570. sprintf(sql, "INSERT INTO historyinfo VALUES ('%s','%s','%s');", data, timeb, his);
  571. if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
  572. {
  573. fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
  574. return -1;
  575. }
  576. }
  577. //列表
  578. int process_admin_list_request(int acceptfd, MSG *msg)
  579. {
  580. memset(history, 0, DATALEN);
  581. sprintf(history,"(passwd:%s) -> cat list",user_passwd);
  582. process_recv_history_request(user_name, history);
  583. char sql[DATALEN] = "";
  584. char **result = NULL;
  585. int row, column;
  586. char *errmsg = NULL;
  587. sprintf(sql, "SELECT * FROM usrinfo;");
  588. if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
  589. {
  590. goto end;
  591. }
  592. printf("查询结果成功\n");
  593. if (row == 0)
  594. {
  595. memset(msg->recvmsg, 0, DATALEN);
  596. strcpy(msg->recvmsg, "no");
  597. send(acceptfd, msg, sizeof(MSG), 0);
  598. sqlite3_free_table(result);
  599. return -1;
  600. }
  601. printf("row=%d column=%d\n", row, column);
  602. int i = 0;
  603. memset(msg->recvmsg, 0, DATALEN);
  604. for (i = 11; i < (row + 1) * column; i++)
  605. {
  606. switch (i % column)
  607. {
  608. case 0:
  609. msg->info.no = atoi(result[i]);
  610. break;
  611. case 1:
  612. msg->info.usertype = atoi(result[i]);
  613. break;
  614. case 2:
  615. strcpy(msg->info.name, result[i]);
  616. break;
  617. case 3:
  618. strcpy(msg->info.passwd, result[i]);
  619. break;
  620. case 4:
  621. msg->info.age = atoi(result[i]);
  622. break;
  623. case 5:
  624. strcpy(msg->info.phone, result[i]);
  625. break;
  626. case 6:
  627. strcpy(msg->info.addr, result[i]);
  628. break;
  629. case 7:
  630. strcpy(msg->info.work, result[i]);
  631. break;
  632. case 8:
  633. strcpy(msg->info.date, result[i]);
  634. break;
  635. case 9:
  636. msg->info.level = atoi(result[i]);
  637. break;
  638. case 10:
  639. msg->info.salary = atoi(result[i]);
  640. break;
  641. default:
  642. break;
  643. }
  644. if (i % column == (column - 1))
  645. {
  646. send(acceptfd, msg, sizeof(MSG), 0);
  647. recv(acceptfd, msg, sizeof(MSG), 0);
  648. memset(msg->recvmsg, 0, DATALEN);
  649. }
  650. }
  651. putchar(10);
  652. end:
  653. memset(msg->recvmsg, 0, DATALEN);
  654. strcpy(msg->recvmsg, "endd");
  655. send(acceptfd, msg, sizeof(MSG), 0);
  656. //释放查询到的结果
  657. sqlite3_free_table(result);
  658. }
  659. //客户端退出
  660. int process_client_quit_request(int acceptfd, MSG *msg)
  661. {
  662. printf("------------%s-----------%d.\n", __func__, __LINE__);
  663. }
  664. //处理客户端请求
  665. int process_client_request(int acceptfd, MSG *msg)
  666. {
  667. //请求的消息类型
  668. switch (msg->msgtype)
  669. {
  670. case USER_LOGIN:
  671. case ADMIN_LOGIN:
  672. process_user_or_admin_login_request(acceptfd, msg); //登录
  673. break;
  674. case USER_MODIFY:
  675. process_user_modify_request(acceptfd, msg); //用户修改
  676. break;
  677. case USER_QUERY:
  678. process_user_query_request(acceptfd, msg); //用户查找
  679. break;
  680. case ADMIN_MODIFY:
  681. process_admin_modify_request(acceptfd, msg); //管理修改
  682. break;
  683. case ADMIN_ADDUSER:
  684. process_admin_adduser_request(acceptfd, msg); //管理添加
  685. break;
  686. case ADMIN_DELUSER:
  687. process_admin_deluser_request(acceptfd, msg); //管理删除
  688. break;
  689. case ADMIN_QUERY:
  690. process_admin_query_request(acceptfd, msg); //管理查找
  691. break;
  692. case ADMIN_HISTORY:
  693. process_admin_history_request(acceptfd, msg); //管理历史
  694. break;
  695. case ADMIN_LIST:
  696. process_admin_list_request(acceptfd, msg); //列表
  697. break;
  698. case QUIT:
  699. process_client_quit_request(acceptfd, msg); //客户端退出
  700. break;
  701. default:
  702. break;
  703. }
  704. }
  705. int main(int argc, const char *argv[])
  706. {
  707. system("clear");
  708. //打开数据库
  709. if (sqlite3_open(STAFF_DATABASE, &db) != SQLITE_OK)
  710. {
  711. printf("%s.\n", sqlite3_errmsg(db));
  712. return -1;
  713. }
  714. printf("database open success\n");
  715. // socket->填充->绑定->监听->等待连接->数据交互->关闭
  716. //创建网络通信的套接字
  717. int socketfd = socket(AF_INET, SOCK_STREAM, 0);
  718. if (socketfd < 0)
  719. {
  720. printf("socket error\n");
  721. return -1;
  722. }
  723. printf("socket success\n");
  724. //允许端口快速重用
  725. int reuse = 1;
  726. if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
  727. {
  728. printf("setsockopt error\n");
  729. return -1;
  730. }
  731. printf("setsockopt success\n");
  732. //填充网络结构体
  733. //填充服务器网路信息结构体
  734. struct sockaddr_in sin;
  735. //填充为IPV4地址
  736. sin.sin_family = AF_INET;
  737. //填充服务器IP
  738. sin.sin_addr.s_addr = inet_addr(S_IP);
  739. //填充服务器端口号
  740. sin.sin_port = htons(atoi(PORT));
  741. //绑定网络套接字和网络结构体
  742. if (bind(socketfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  743. {
  744. printf("bind error\n");
  745. return -1;
  746. }
  747. printf("bind success\n");
  748. //监听套接字,将主动套接字转化为被动套接字
  749. if (listen(socketfd, 10) < 0)
  750. {
  751. printf("listen error\n");
  752. return -1;
  753. }
  754. printf("listen success\n");
  755. //通过select实现并发
  756. //客户端网络信息结构体
  757. struct sockaddr_in cin;
  758. socklen_t addrlen = sizeof(cin);
  759. //创建一个读集合
  760. fd_set readfds, tempfds;
  761. //将集合清空
  762. FD_ZERO(&readfds);
  763. FD_ZERO(&tempfds);
  764. //将sfd文件描述符添加到集合
  765. FD_SET(socketfd, &readfds);
  766. //最大文件描述符
  767. int maxfd = socketfd;
  768. //接收select返回值
  769. int select_res = 0;
  770. MSG msg;
  771. ssize_t recvbytes = 0;
  772. int acceptfd = -1;
  773. int i = 0;
  774. //定义一个数组,存储每次连接成功的客户端的信息
  775. struct sockaddr_in save_addr[1024 - 4];
  776. while (1)
  777. {
  778. tempfds = readfds;
  779. //>0, 三个集合中成功触发事件的文件描述符个数 =0超时 =-1失败;
  780. select_res = select(maxfd + 1, &tempfds, NULL, NULL, NULL);
  781. if (select_res < 0)
  782. {
  783. printf("select error\n");
  784. return -1;
  785. }
  786. else if (select_res == 0)
  787. {
  788. printf("select timeout\n");
  789. return -1;
  790. }
  791. for (i = 0; i <= maxfd; i++)
  792. {
  793. //判断0~maxfd这些文件描述符在不在集合中
  794. if (FD_ISSET(i, &tempfds) == 0)
  795. {
  796. continue;
  797. }
  798. //能运行到当前位置,则说明i所代表的文件描述符有事件产生
  799. //判断是否是集合里关注的事件
  800. if (socketfd == i)
  801. {
  802. printf("触发客户端连接事件:");
  803. fflush(stdout);
  804. //数据交互
  805. acceptfd = accept(socketfd, (struct sockaddr *)&cin, &addrlen);
  806. if (acceptfd == -1)
  807. {
  808. printf("acceptfd error\n");
  809. return -1;
  810. }
  811. //网络字节序的IP-->点分十进制 网络字节序的port--->本机字节序
  812. printf("[%s : %d] acceptfd = %d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), acceptfd);
  813. memset(history, 0, DATALEN);
  814. sprintf(history,"[%s : %d] acceptfd[%d]",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), acceptfd);
  815. process_recv_history_request("connect", history);
  816. //将cin存储到 save_addr数组对应的位置,
  817. // acceptfd==4,则存储到下标为0,acceptfd==5,存储到下标为1,acceptfd==n,则存储到下标为n-4的位置
  818. save_addr[acceptfd - 4] = cin;
  819. //将acceptfd添加到集合中
  820. FD_SET(acceptfd, &readfds);
  821. //更新maxfd
  822. maxfd = maxfd > acceptfd ? maxfd : acceptfd;
  823. }
  824. else
  825. {
  826. //客户端交互事件
  827. bzero(&msg, sizeof(MSG));
  828. recvbytes = recv(i, &msg, sizeof(MSG), 0);
  829. if (recvbytes == -1)
  830. {
  831. // <0 错误
  832. printf("recv error\n");
  833. continue;
  834. }
  835. else if (recvbytes == 0)
  836. {
  837. // ==0
  838. printf("[%s : %d] acceptfd = %d client off-line\n",
  839. inet_ntoa(save_addr[i - 4].sin_addr), ntohs(save_addr[i - 4].sin_port), i);
  840. memset(history, 0, DATALEN);
  841. sprintf(history,"[%s : %d] acceptfd = [%d]",inet_ntoa(save_addr[i - 4].sin_addr), ntohs(save_addr[i - 4].sin_port), i);
  842. process_recv_history_request("lost connect", history);
  843. //关闭文件描述符
  844. close(i);
  845. //将文件描述符从集合中剔除
  846. FD_CLR(i, &readfds);
  847. //更新maxfd
  848. for (int i = maxfd; i > 0; i--)
  849. {
  850. if (FD_ISSET(i, &readfds))
  851. {
  852. maxfd = i;
  853. break;
  854. }
  855. }
  856. printf("peer shutdown.\n");
  857. }
  858. else
  859. {
  860. //处理客户端请求
  861. process_client_request(i, &msg);
  862. }
  863. }
  864. }
  865. }
  866. close(socketfd);
  867. return 0;
  868. }

客户端(client.h文件):

  1. void do_admin_query(int sockfd, MSG *msg);
  2. void do_admin_modification(int sockfd, MSG *msg);
  3. void do_admin_adduser(int sockfd, MSG *msg);
  4. void do_admin_deluser(int sockfd, MSG *msg);
  5. void do_admin_history(int sockfd, MSG *msg);
  6. void do_admin_list(int sockfd, MSG *msg);
  7. void admin_menu(int sockfd, MSG *msg);
  8. void do_user_query(int sockfd, MSG *msg);
  9. void do_user_modification(int sockfd, MSG *msg);
  10. void user_menu(int sockfd, MSG *msg);
  11. int admin_or_user_login(int sockfd, MSG *msg);
  12. int do_login(int socketfd);

客户端(client.c文件):

  1. #include "common.h"
  2. #include "client.h"
  3. /**************************************
  4. *函数名:do_query
  5. *参 数:消息结构体
  6. *功 能:管理员查询
  7. ****************************************/
  8. void do_admin_query(int sockfd, MSG *msg)
  9. {
  10. system("clear");
  11. memset(msg, 0, sizeof(MSG));
  12. msg->msgtype = ADMIN_QUERY;
  13. char name[NAMELEN] = "";
  14. printf("Please enter find no:");
  15. scanf("%s", name);
  16. while (getchar() != '\n')
  17. ;
  18. strcpy(msg->recvmsg, name);
  19. //发送查询请求
  20. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  21. {
  22. printf("Sending the account to the server error\n");
  23. return;
  24. }
  25. //接受服务器响应
  26. while (1)
  27. {
  28. recv(sockfd, msg, sizeof(MSG), 0);
  29. if (!strncmp(msg->recvmsg, "end", 3))
  30. {
  31. printf("find success\n");
  32. return;
  33. }
  34. if (!strncmp(msg->recvmsg, "no", 2))
  35. {
  36. printf("find error\n");
  37. return;
  38. }
  39. printf("----------------------------------\n");
  40. 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);
  41. printf("----------------------------------\n");
  42. }
  43. }
  44. /**************************************
  45. *函数名:admin_modification
  46. *参 数:消息结构体
  47. *功 能:管理员修改
  48. ****************************************/
  49. void do_admin_modification(int sockfd, MSG *msg) //管理员修改
  50. {
  51. system("clear");
  52. memset(msg, 0, sizeof(MSG));
  53. msg->msgtype = ADMIN_MODIFY;
  54. int opt = 0;
  55. int tem;
  56. char str1[NAMELEN] = "";
  57. char str2[DATALEN] = "";
  58. char str3[PASSLEN] = "";
  59. printf("please enter user name:");
  60. scanf("%s",msg->username);
  61. 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:");
  62. scanf("%d", &opt);
  63. while(getchar()!='\n');
  64. switch (opt)
  65. {
  66. case 1:
  67. msg->flags = 1;
  68. printf("please enter no:");
  69. scanf("%d", &tem);
  70. msg->info.no = tem;
  71. break;
  72. case 2:
  73. msg->flags = 2;
  74. printf("please enter usertype:");
  75. scanf("%d", &tem);
  76. msg->info.usertype = tem;
  77. break;
  78. case 3:
  79. msg->flags = 3;
  80. printf("please enter name:");
  81. fgets(str1,NAMELEN,stdin);
  82. str1[strlen(str1)-1]='\0';
  83. strcpy(msg->info.name, str1);
  84. break;
  85. case 4:
  86. msg->flags = 4;
  87. printf("please enter passwd:");
  88. fgets(str3,PASSLEN,stdin);
  89. str3[strlen(str3)-1]='\0';
  90. strcpy(msg->info.passwd, str1);
  91. break;
  92. case 5:
  93. msg->flags = 5;
  94. printf("please enter age:");
  95. scanf("%d", &tem);
  96. msg->info.age = tem;
  97. break;
  98. case 6:
  99. msg->flags = 6;
  100. printf("please enter phone:");
  101. fgets(str1,NAMELEN,stdin);
  102. str1[strlen(str1)-1]='\0';
  103. strcpy(msg->info.phone, str1);
  104. break;
  105. case 7:
  106. msg->flags = 7;
  107. printf("please enter addr:");
  108. fgets(str2,DATALEN,stdin);
  109. str2[strlen(str2)-1]='\0';
  110. strcpy(msg->info.addr, str2);
  111. break;
  112. case 8:
  113. msg->flags = 8;
  114. printf("please enter work:");
  115. fgets(str2,DATALEN,stdin);
  116. str2[strlen(str2)-1]='\0';
  117. strcpy(msg->info.work, str2);
  118. break;
  119. case 9:
  120. msg->flags = 9;
  121. printf("please enter date:");
  122. fgets(str2,DATALEN,stdin);
  123. str2[strlen(str2)-1]='\0';
  124. strcpy(msg->info.date, str2);
  125. break;
  126. case 10:
  127. msg->flags = 10;
  128. printf("please enter level:");
  129. scanf("%d", &tem);
  130. msg->info.level = tem;
  131. break;
  132. case 11:
  133. msg->flags = 11;
  134. printf("please enter salary:");
  135. scanf("%d", &tem);
  136. msg->info.salary = tem;
  137. break;
  138. default:
  139. printf("enter error\n");
  140. return;
  141. }
  142. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  143. {
  144. printf("Sending the account to the server error\n");
  145. return;
  146. }
  147. system("clear");
  148. recv(sockfd, msg, sizeof(MSG), 0);
  149. if (!strncmp(msg->recvmsg, "ok", 2))
  150. {
  151. printf("user change success\n");
  152. return;
  153. }
  154. else if(!strncmp(msg->recvmsg, "no", 2))
  155. {
  156. printf("user change error\n");
  157. return;
  158. }
  159. }
  160. /**************************************
  161. *函数名:admin_adduser
  162. *参 数:消息结构体
  163. *功 能:管理员创建用户
  164. ****************************************/
  165. void do_admin_adduser(int sockfd, MSG *msg) //管理员添加用户
  166. {
  167. system("clear");
  168. int tem;
  169. char str1[NAMELEN] = "";
  170. char str2[DATALEN] = "";
  171. char str3[PASSLEN] = "";
  172. memset(msg, 0, sizeof(MSG));
  173. msg->msgtype = ADMIN_ADDUSER;
  174. printf("please enter no:");
  175. scanf("%d", &tem);
  176. msg->info.no = tem;
  177. printf("please enter usertype:");
  178. scanf("%d", &tem);
  179. msg->info.usertype = tem;
  180. while (getchar() != '\n');
  181. printf("please enter name:");
  182. fgets(str1,NAMELEN,stdin);
  183. str1[strlen(str1)-1]='\0';
  184. strcpy(msg->info.name, str1);
  185. printf("please enter passwd:");
  186. fgets(str3,PASSLEN,stdin);
  187. str3[strlen(str3)-1]='\0';
  188. strcpy(msg->info.passwd, str3);
  189. printf("please enter age:");
  190. scanf("%d", &tem);
  191. msg->info.age = tem;
  192. while (getchar() != '\n');
  193. printf("please enter phone:");
  194. fgets(str1,NAMELEN,stdin);
  195. str1[strlen(str1)-1]='\0';
  196. strcpy(msg->info.phone, str1);
  197. printf("please enter addr:");
  198. fgets(str2,DATALEN,stdin);
  199. str2[strlen(str2)-1]='\0';
  200. strcpy(msg->info.addr, str2);
  201. printf("please enter work:");
  202. fgets(str2,DATALEN,stdin);
  203. str2[strlen(str2)-1]='\0';
  204. strcpy(msg->info.work, str2);
  205. printf("please enter date:");
  206. fgets(str2,DATALEN,stdin);
  207. str2[strlen(str2)-1]='\0';
  208. strcpy(msg->info.date, str2);
  209. printf("please enter level:");
  210. scanf("%d", &tem);
  211. msg->info.level = tem;
  212. printf("please enter salary:");
  213. scanf("%d", &tem);
  214. msg->info.salary = tem;
  215. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  216. {
  217. printf("Sending the account to the server error\n");
  218. return;
  219. }
  220. recv(sockfd, msg, sizeof(MSG), 0);
  221. if (!strncmp(msg->recvmsg, "ok", 2))
  222. {
  223. printf("user add success\n");
  224. return;
  225. }
  226. else if (!strncmp(msg->recvmsg, "no", 2))
  227. {
  228. printf("user add error\n");
  229. return;
  230. }
  231. printf("user add error\n");
  232. }
  233. /**************************************
  234. *函数名:admin_deluser
  235. *参 数:消息结构体
  236. *功 能:管理员删除用户
  237. ****************************************/
  238. void do_admin_deluser(int sockfd, MSG *msg) //管理员删除用户
  239. {
  240. system("clear");
  241. msg->msgtype = ADMIN_DELUSER;
  242. int no = 0;
  243. printf("pelase enter delete user NO:");
  244. scanf("%d", &no);
  245. msg->info.no = no;
  246. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  247. {
  248. printf("Sending the account to the server error\n");
  249. return;
  250. }
  251. recv(sockfd, msg, sizeof(MSG), 0);
  252. if (!strncmp(msg->recvmsg, "ok", 2))
  253. {
  254. printf("user delete success\n");
  255. return;
  256. }
  257. else if (!strncmp(msg->recvmsg, "no", 2))
  258. {
  259. printf("user delete error\n");
  260. return;
  261. }
  262. }
  263. /**************************************
  264. *函数名:do_history
  265. *参 数:消息结构体
  266. *功 能:管理员查看历史记录
  267. ****************************************/
  268. void do_admin_history(int sockfd, MSG *msg)
  269. {
  270. system("clear");
  271. memset(msg, 0, sizeof(MSG));
  272. msg->msgtype = ADMIN_HISTORY;
  273. putchar(10);
  274. printf(" %s | %s | %s \n","data","time","log");
  275. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  276. {
  277. printf("Sending the account to the server error\n");
  278. return;
  279. }
  280. while (1)
  281. {
  282. recv(sockfd, msg, sizeof(MSG), 0);
  283. if (msg->flags == 1)
  284. {
  285. printf("find success\n");
  286. break;
  287. }
  288. if (msg->flags == 2)
  289. {
  290. printf("find error\n");
  291. break;
  292. }
  293. printf("%s",msg->recvmsg);
  294. send(sockfd, msg, sizeof(MSG), 0);
  295. }
  296. }
  297. void do_admin_list(int sockfd, MSG *msg)
  298. {
  299. system("clear");
  300. memset(msg, 0, sizeof(MSG));
  301. msg->msgtype = ADMIN_LIST;
  302. char name[NAMELEN] = "";
  303. //发送查询请求
  304. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  305. {
  306. printf("Sending the account to the server error\n");
  307. return;
  308. }
  309. //接受服务器响应
  310. while (1)
  311. {
  312. recv(sockfd, msg, sizeof(MSG), 0);
  313. if (!strncmp(msg->recvmsg, "endd", 4))
  314. {
  315. printf("find success\n");
  316. return;
  317. }
  318. if (!strncmp(msg->recvmsg, "no", 2))
  319. {
  320. printf("find error\n");
  321. return;
  322. }
  323. //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);
  324. printf("----------------------------------\n");
  325. 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);
  326. printf("----------------------------------\n");
  327. send(sockfd, msg, sizeof(MSG), 0);
  328. }
  329. }
  330. /**************************************
  331. *函数名:admin_menu
  332. *参 数:套接字、消息结构体
  333. *功 能:管理员菜单
  334. ****************************************/
  335. void admin_menu(int sockfd, MSG *msg)
  336. {
  337. int op = -1;
  338. printf(" ************ 1 find ************\n");
  339. printf(" ************ 2 change ************\n");
  340. printf(" ************ 3 add ************\n");
  341. printf(" ************ 4 delete ************\n");
  342. printf(" ************ 5 list ************\n");
  343. printf(" ************ 6 clean ************\n");
  344. printf(" ************ 7 history ************\n");
  345. printf(" ************ 0 quit ************\n");
  346. printf("please enter your option:");
  347. scanf("%d", &op);
  348. while(getchar()!='\n');
  349. if(op < 0 || op > 7)
  350. {
  351. system("clear");
  352. printf("输入错误 请重新输入\n");
  353. admin_menu(sockfd,msg);
  354. }
  355. switch (op)
  356. {
  357. case 0:
  358. system("clear");
  359. do_login(sockfd);
  360. break;
  361. case 1:
  362. do_admin_query(sockfd, msg);
  363. break;
  364. case 2:
  365. do_admin_modification(sockfd, msg);
  366. break;
  367. case 3:
  368. do_admin_adduser(sockfd, msg);
  369. break;
  370. case 4:
  371. do_admin_deluser(sockfd, msg);
  372. break;
  373. case 5:
  374. do_admin_list(sockfd, msg);
  375. break;
  376. case 6:
  377. system("clear");
  378. break;
  379. case 7:
  380. do_admin_history(sockfd,msg);
  381. break;
  382. default:
  383. printf("enter error\n");
  384. return;
  385. }
  386. }
  387. /**************************************
  388. *函数名:do_query
  389. *参 数:消息结构体
  390. *功 能:用户查找
  391. ****************************************/
  392. void do_user_query(int sockfd, MSG *msg)
  393. {
  394. system("clear");
  395. memset(msg, 0, sizeof(MSG));
  396. msg->msgtype = USER_QUERY;
  397. strcpy(msg->username, user_name);
  398. strcpy(msg->passwd,user_passwd);
  399. //发送查询请求
  400. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  401. {
  402. printf("Sending the account to the server error\n");
  403. return;
  404. }
  405. //接受服务器响应
  406. while(1)
  407. {
  408. recv(sockfd, msg, sizeof(MSG), 0);
  409. if (!strncmp(msg->recvmsg, "end", 3))
  410. {
  411. printf("find success\n");
  412. return;
  413. }
  414. if (!strncmp(msg->recvmsg, "no", 2))
  415. {
  416. printf("find error\n");
  417. return;
  418. }
  419. printf("----------------------------------\n");
  420. 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);
  421. printf("----------------------------------\n");
  422. }
  423. }
  424. /**************************************
  425. *函数名:do_modification
  426. *参 数:消息结构体
  427. *功 能:用户修改
  428. ****************************************/
  429. void do_user_modification(int sockfd, MSG *msg)
  430. {
  431. system("clear");
  432. memset(msg, 0, sizeof(MSG));
  433. msg->msgtype = USER_MODIFY;
  434. strcpy(msg->username, user_name);
  435. strcpy(msg->passwd,user_passwd);
  436. int opt = 0;
  437. int tem;
  438. char str1[NAMELEN] = "";
  439. char str2[DATALEN] = "";
  440. char str3[PASSLEN] = "";
  441. 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:");
  442. scanf("%d", &opt);
  443. while(getchar()!='\n');
  444. switch (opt)
  445. {
  446. case 1:
  447. msg->flags = 1;
  448. printf("please enter no:");
  449. scanf("%d", &tem);
  450. msg->info.no = tem;
  451. break;
  452. case 2:
  453. msg->flags = 2;
  454. printf("please enter usertype:");
  455. scanf("%d", &tem);
  456. msg->info.usertype = tem;
  457. break;
  458. case 3:
  459. msg->flags = 3;
  460. printf("please enter name:");
  461. fgets(str1,NAMELEN,stdin);
  462. str1[strlen(str1)-1]='\0';
  463. strcpy(msg->info.name, str1);
  464. break;
  465. case 4:
  466. msg->flags = 4;
  467. printf("please enter passwd:");
  468. fgets(str3,PASSLEN,stdin);
  469. str3[strlen(str3)-1]='\0';
  470. strcpy(msg->info.passwd, str3);
  471. break;
  472. case 5:
  473. msg->flags = 5;
  474. printf("please enter age:");
  475. scanf("%d", &tem);
  476. msg->info.age = tem;
  477. break;
  478. case 6:
  479. msg->flags = 6;
  480. printf("please enter phone:");
  481. fgets(str1,NAMELEN,stdin);
  482. str1[strlen(str1)-1]='\0';
  483. strcpy(msg->info.phone, str1);
  484. break;
  485. case 7:
  486. msg->flags = 7;
  487. printf("please enter addr:");
  488. fgets(str2,DATALEN,stdin);
  489. str2[strlen(str2)-1]='\0';
  490. strcpy(msg->info.addr, str2);
  491. break;
  492. case 8:
  493. msg->flags = 8;
  494. printf("please enter work:");
  495. fgets(str2,DATALEN,stdin);
  496. str2[strlen(str2)-1]='\0';
  497. strcpy(msg->info.work, str2);
  498. break;
  499. case 9:
  500. msg->flags = 9;
  501. printf("please enter date:");
  502. fgets(str2,DATALEN,stdin);
  503. str2[strlen(str2)-1]='\0';
  504. strcpy(msg->info.date, str2);
  505. break;
  506. case 10:
  507. msg->flags = 10;
  508. printf("please enter level:");
  509. scanf("%d", &tem);
  510. msg->info.level = tem;
  511. break;
  512. case 11:
  513. msg->flags = 11;
  514. printf("please enter salary:");
  515. scanf("%d", &tem);
  516. msg->info.salary = tem;
  517. break;
  518. default:
  519. printf("enter error\n");
  520. return;
  521. }
  522. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  523. {
  524. printf("Sending the account to the server error\n");
  525. return;
  526. }
  527. system("clear");
  528. recv(sockfd, msg, sizeof(MSG), 0);
  529. if (!strncmp(msg->recvmsg, "ok", 2))
  530. {
  531. printf("user change success\n");
  532. return;
  533. }
  534. else if(!strncmp(msg->recvmsg, "no", 2))
  535. {
  536. printf("user change error\n");
  537. return;
  538. }
  539. }
  540. /**************************************
  541. *函数名:user_menu
  542. *参 数:消息结构体
  543. *功 能:用户菜单
  544. ****************************************/
  545. void user_menu(int sockfd, MSG *msg)
  546. {
  547. int op = -1;
  548. printf(" ************ 1 find ************\n");
  549. printf(" ************ 2 change ************\n");
  550. printf(" ************ 3 clean ************\n");
  551. printf(" ************ 0 quit ************\n");
  552. printf("please enter your option:");
  553. scanf("%d", &op);
  554. while(getchar()!='\n');
  555. if(op < 0 || op > 3)
  556. {
  557. system("clear");
  558. printf("输入错误 请重新输入\n");
  559. user_menu(sockfd,msg);
  560. }
  561. switch (op)
  562. {
  563. case 0:
  564. system("clear");
  565. do_login(sockfd);
  566. break;
  567. case 1:
  568. do_user_query(sockfd, msg);
  569. break;
  570. case 2:
  571. do_user_modification(sockfd, msg);
  572. break;
  573. case 3:
  574. system("clear");
  575. break;
  576. default:
  577. printf("enter error\n");
  578. break;
  579. }
  580. }
  581. int admin_or_user_login(int sockfd, MSG *msg)
  582. {
  583. //输入用户名和密码
  584. memset(msg->username, 0, NAMELEN);
  585. printf("请输入用户名:");
  586. scanf("%s", msg->username);
  587. getchar();
  588. memset(msg->passwd, 0, DATALEN);
  589. printf("请输入密码: ");
  590. scanf("%s", msg->passwd);
  591. getchar();
  592. strcpy(user_name,msg->username);
  593. strcpy(user_passwd,msg->passwd);
  594. //发送登陆请求
  595. if (send(sockfd, msg, sizeof(MSG), 0) < 0)
  596. {
  597. printf("Sending the account to the server error\n");
  598. return -1;
  599. }
  600. //接受服务器响应
  601. recv(sockfd, msg, sizeof(MSG), 0);
  602. //判断是否登陆成功
  603. if (strncmp(msg->recvmsg, "OK", 2) == 0)
  604. {
  605. if (msg->usertype == ADMIN)
  606. {
  607. system("clear");
  608. printf("亲爱的管理员,欢迎您登陆员工管理系统!\n");
  609. while (1)
  610. {
  611. admin_menu(sockfd, msg);
  612. }
  613. }
  614. else if (msg->usertype == USER)
  615. {
  616. system("clear");
  617. printf("亲爱的用户,欢迎您登陆员工管理系统!\n");
  618. while (1)
  619. {
  620. user_menu(sockfd, msg);
  621. }
  622. }
  623. }
  624. else
  625. {
  626. printf("登陆失败!%s\n", msg->recvmsg);
  627. admin_or_user_login(sockfd,msg);
  628. }
  629. return 0;
  630. }
  631. /************************************************
  632. *函数名:do_login
  633. *参 数:套接字、消息结构体
  634. *返回值:是否登陆成功
  635. *功 能:登陆
  636. *************************************************/
  637. int do_login(int socketfd)
  638. {
  639. int n;
  640. MSG msg;
  641. while (1)
  642. {
  643. printf("**********************************\n");
  644. printf("******** 1: 管理员模式 ********\n");
  645. printf("******** 2:普通用户模式 ********\n");
  646. printf("******** 0: 退出 ********\n");
  647. printf("**********************************\n");
  648. printf("请输入您的选择(数字)>> ");
  649. scanf("%d", &n);
  650. while(getchar()!='\n');
  651. if(n < 0 || n > 2)
  652. {
  653. system("clear");
  654. printf("输入错误 请重新输入\n");
  655. do_login(socketfd);
  656. }
  657. switch (n)
  658. {
  659. case 1:
  660. //管理员模式登录
  661. msg.msgtype = ADMIN_LOGIN; // 1
  662. msg.usertype = ADMIN; // 0
  663. break;
  664. case 2:
  665. //普通用户登录
  666. msg.msgtype = USER_LOGIN;
  667. msg.usertype = USER;
  668. break;
  669. case 0:
  670. //退出
  671. msg.msgtype = QUIT;
  672. if (send(socketfd, &msg, sizeof(MSG), 0) < 0)
  673. {
  674. perror("do_login send");
  675. return -1;
  676. }
  677. close(socketfd);
  678. exit(0);
  679. default:
  680. printf("您的输入有误,请重新输入\n");
  681. }
  682. admin_or_user_login(socketfd, &msg);
  683. }
  684. }
  685. int main(int argc, const char *argv[])
  686. {
  687. // socket->填充->绑定->监听->等待连接->数据交互->关闭
  688. system("clear");
  689. int socketfd;
  690. //创建网络通信的套接字 流式套接字
  691. if (-1 == (socketfd = socket(AF_INET, SOCK_STREAM, 0)))
  692. {
  693. printf("socket error\n");
  694. return -1;
  695. }
  696. printf("socket success\n");
  697. //填充网络结构体
  698. //填充服务器网路信息结构体
  699. struct sockaddr_in sin;
  700. //填充为IPV4地址
  701. sin.sin_family = AF_INET;
  702. //填充服务器IP
  703. sin.sin_addr.s_addr = inet_addr(IP);
  704. //填充服务器端口号
  705. sin.sin_port = htons(atoi(PORT));
  706. //连接服务器
  707. if (-1 == connect(socketfd, (struct sockaddr *)&sin, sizeof(sin)))
  708. {
  709. printf("connect error\n");
  710. return -1;
  711. }
  712. printf("connect suceess\n");
  713. //登陆
  714. do_login(socketfd);
  715. //关闭套接字
  716. close(socketfd);
  717. return 0;
  718. }

原文链接:https://blog.csdn.net/weixin_43386810/article/details/127589253



所属网站分类: 技术文章 > 博客

作者:天天在家

链接:http://www.javaheidong.com/blog/article/597348/01f3fe87f35447dda1dd/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)