• 项目 - 员工信息管理系统


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

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

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

    项目名称:员工管理系统

    项目时间: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
    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//根据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
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    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. }

  • 相关阅读:
    微信小程序 - WXML 模板语法 - 条件渲染
    idea集成swagger创建接口文档
    vmware ubuntu 操作
    2023-10-25 精神分析-领悟新技术的错误做法-持续数年的错误做法-记录与分析
    rpmbuild时为什么会出现空的debugsourcefiles.list?
    【python】(八)python类型注解
    STM32注入通道
    常用百宝箱——日志处理
    简单大方的自我介绍 PPT 格式
    通过python实现分析出生日期辨识你的星座 出生日期判断星座
  • 原文地址:https://blog.csdn.net/weixin_43386810/article/details/127589253