嵌入式linux-sqlite3数据库,多进程并发服务器,在线词典

2019-07-12 23:07发布

文章目录

1,简介:

1,在线词典功能,分为客户端和服务器端
2,客户端有三个模块:注册、登录、查询(查询单词、查询历史记录)
3,服务器端要实现多并发服务器,这里采用多进程并发服务器:注册、登录、查询(查询单词、查询历史记录)
4,用户分为普通用户和管理员用户:管理员用户可以查询所有普通用户的历史记录,还可以看到词库中未定义的单词查询记录,普通用户只能查到自己的,词库中中有定义的记录
5,客户端和服务器通信只要通过一个信息结构体实现: typedef struct{ int flag; //1:usr or 2:root int type; char name[N]; char data[256]; //password or word }MSG; 6,服务器端有单词词库
7,服务器端有两张数据库表格,一张用来存放用户信息,一张用来存放用户单词查询记录
8,多进程并发服务器要做僵尸进程处理

2,框架图

2.1,客户端框架

在这里插入图片描述

2.1,服务器端框架

在这里插入图片描述

3,代码

3.1,客户端代码

#include #include #include #include #include #include #include #include #include #define N 20 #define R 1 #define L 2 #define Q 3 #define H 4 #define USR 1 #define ROOT 2 typedef struct{ int flag; //1:usr or 2:root int type; char name[N]; char data[256]; //password or word }MSG; int do_client(int sockfd); int do_register(int connectfd,MSG *msg); int do_login(int connectfd,MSG *msg); int do_query(int connectfd,MSG *msg); int do_history(int connectfd,MSG *msg); int main(int argc, const char *argv[]) { int serverfd; struct sockaddr_in sin; if(argc != 3) { printf("usage: %s ",argv[0]); exit(0); } //创建流式套接字 if((serverfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("socket"); exit(-1); } //填充协议地址结构体 bzero(&sin,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(atoi(argv[2])); sin.sin_addr.s_addr = inet_addr(argv[1]); //连接服务器 if(connect(serverfd,(struct sockaddr *)&sin,sizeof(sin)) < 0) { perror("connect"); goto _error1; } do_client(serverfd); _error1: close(serverfd); return 0; } int do_client(int sockfd) { MSG msg; bzero(&msg,sizeof(msg)); msg.flag = -1; while(msg.flag < 0) { printf("Please choose permission [1:usr 2:root]"); if(scanf("%d",&msg.flag) == 0) msg.flag = -1; while(getchar() != ' '); if(msg.flag != 1 && msg.flag != 2) msg.flag = -1; } /* 注册登录模块 */ while(1) { msg.type = -1; while(msg.type < 0) { printf("******************************************** "); printf("*1:register 2:login 3:quite * "); printf("******************************************** "); printf("PLease choose:"); if(scanf("%d",&msg.type) == 0) msg.type = -1; while(getchar() != ' '); } switch (msg.type) { case R: { do_register(sockfd,&msg); break; } case L: { if(do_login(sockfd,&msg) == 1) { goto _NEXT; } break; } case 3: { close(sockfd); printf("Exit the online dictionary program "); exit(0); break; } default: printf("Error cmd. "); } } _NEXT: /* 查询模块 */ while(1) { msg.type = -1; while(msg.type < 0) { printf("******************************************** "); printf("*1:query_word 2:history_record 3:quite * "); printf("******************************************** "); printf("Please choose:"); if(scanf("%d",&msg.type) == 0) msg.type = -1; while(getchar() != ' '); } switch (msg.type) { case 1: { msg.type = Q; do_query(sockfd,&msg); break; } case 2: { msg.type = H; do_history(sockfd,&msg); break; } case 3: { close(sockfd); printf("Exit the online dictionary program "); exit(0); break ; } default: printf("Error cmd. "); } } } int do_register(int connectfd,MSG *msg) { char str[20]; int flag; while(1) { printf("PLease input name:"); if(scanf("%s",msg->name)){}; while(getchar() != ' '); flag = -1; while(flag < 0) { printf("PLease input password:"); if(scanf("%s",str)){}; while(getchar() != ' '); printf("Please confirm password:"); if(scanf("%s",msg->data)){}; while(getchar() != ' '); if(strncmp(msg->data,str,strlen(str)) == 0) { flag = 1; } else { printf("Entered passwords differ,Please re-enter them. "); } } if(send(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_register fail to send"); return -1; } if(recv(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_register fail to recv"); return -1; } if(strncasecmp(msg->data,"ok",strlen("ok")) == 0) { printf("register success. "); return 1; break; } else { printf("%s ",msg->data); printf("re-register or cancel [1:re-register 2:cancel]"); int tmp; if(scanf("%d",&tmp)){}; while(getchar() != ' '); if(tmp == 2) break; } } return 0; } int do_login(int connectfd,MSG *msg) { while(1) { printf("PLease input name:"); if(scanf("%s",msg->name)){}; while(getchar() != ' '); printf("PLease input password:"); if(scanf("%s",msg->data)){}; while(getchar() != ' '); if(send(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_login fail to send"); return -1; } if(recv(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_login fail to recv"); return -1; } if(strncasecmp(msg->data,"ok",strlen("ok")) == 0) { printf("login success. "); return 1; break; } else { printf("%s ",msg->data); printf("re-login or cancel [1:re-login 2:cancel]"); int tmp; if(scanf("%d",&tmp)){}; while(getchar() != ' '); if(tmp == 2) break; } } return 0; } int do_query(int connectfd,MSG *msg) { while(1) { printf("Please input query_word('#' exit):"); if(scanf("%s",msg->data)){}; while(getchar() != ' '); /* 返回上级菜单 */ if(strncmp(msg->data,"#",strlen("#")) == 0) { break; } /* 把含有有查询单词的消息结构体发送给服务器 */ if(send(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_query fail to send."); return -1; } /* 阻塞接受 */ if(recv(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_query fail to recv."); return -1; } /* 处理从服务器接受的信息 */ printf("%s",msg->data); } return 0; } int do_history(int connectfd,MSG *msg) { if(send(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_history fail to send"); return -1; } while(1) { if(recv(connectfd,msg,sizeof(MSG),0) < 0) { perror("do_history fail to recv"); return -1; } #if 1 if(msg->data[0] == '