ser.c
#include <head.h>
//定义线程体结构体
struct cli_msg
{
int newfd;
struct sockaddr_in cin;
sqlite3 **db;
};
//定义信息结构体
typedef struct MSG
{
char code;//'L':登录 'E':注册 'Q':退出 'F':查询单词 'S':查询历史记录
char user[9];
char passwd[9];
char msg[128];
}msg_t;
//添加用户信息
int do_add_user(sqlite3 *db,msg_t buf);
//创建电子词典数据库
int create_dictionary_db(sqlite3 **db);
//创建用户表
int create_user_table(sqlite3 **value);
//定义查找用户
int do_search_user(sqlite3 *db,msg_t buf);
//关闭数据库
int close_dictionary_db(sqlite3 **db);
//定义查找密码
int do_search_pass(sqlite3 *db,msg_t buf);
//定义注册功能
void use_register(sqlite3 **db,msg_t buf,int newfd);
//定义登录功能
void user_login(sqlite3 **db,msg_t buf,int newfd,char *user);
//创建单词表
int create_word_table(sqlite3 **value);
//添加单词信息
int do_add_word(sqlite3 **value);
//定义查找单词功能
void do_search_word(sqlite3 **value,msg_t buf,char *user,int newfd);
//创建历史记录表
int create_history_table(sqlite3 *db,msg_t buf);
//添加历史信息
int do_add_history(sqlite3 *db,char *user,char *English,char *Chinese);
//定义查找历史记录
int do_search_history(sqlite3 **value,msg_t buf,int newfd,char *user);
void *deal_cli_msg(void *arg)
{
int newfd=((struct cli_msg*)arg)->newfd;
struct sockaddr_in cin =((struct cli_msg*)arg)->cin;
sqlite3 **db=((struct cli_msg*)arg)->db;
msg_t buf;
char user[36]="";
while(1)
{
int flag;
bzero(&buf.msg,sizeof(buf.msg));
int ret=recv(newfd,&buf,sizeof(buf),0);
if(ret==-1)
{
ERR_MSG("recv");
}else if(ret==0)
{
printf("%s:客户端下线\n",buf.user);
break;
}
printf("%s : %c \n",buf.user,buf.code);
//-------------------------发送
switch(buf.code)
{
case 'E':
use_register(db,buf,newfd);
break;
case 'L':
user_login(db,buf,newfd,user);
break;
case 'F':
puts(user);
do_search_word(db,buf,user,newfd);
break;
case 'S':
do_search_history(db,buf,newfd,user);
break;
}
}
}
//定义注册功能
void use_register(sqlite3 **db,msg_t buf,int newfd)
{
int flag;
char sen[128];
flag=do_search_user(*db,buf);
if(flag==0)//0表示不存在
{
do_add_user(*db,buf);
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"register success");
//创建历史记录表
create_history_table(*db,buf);
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
}
else if(flag==1)//1:表示存在
{
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"user exist");
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
}
}
//定义登录功能
void user_login(sqlite3 **db,msg_t buf,int newfd,char *user)
{
int flag;
flag=do_search_user(*db,buf);
if(flag==0)//0表示不存在
{
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"user unexist");
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
}
else if(flag==1)//1:表示存在
{
flag=do_search_pass(*db,buf);
if(flag==1)
{
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"login success");
strcpy(user,buf.user);
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
}
else
{
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"passwd error");
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
}
}
}
//创建电子词典数据库
int create_dictionary_db(sqlite3 **db)
{
if(sqlite3_open("./dictionary.db",db)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_open error,errcode:%d,errmsg:%s\n",__LINE__,sqlite3_errcode(*db),sqlite3_errmsg(*db));
return -1;
}
printf("sqlite3_open success\n");
return 0;
}
//创建用户表
int create_user_table(sqlite3 **value)
{
sqlite3 *db=*value;
char sql[]="create table if not exists User_t(user char primary key,passwd char);";
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
*value=db;
printf("create_user_table success\n");
return 0;
}
//创建历史记录表
int create_history_table(sqlite3 *db,msg_t buf)
{
char sql[120]="";
sprintf(sql,"create table if not exists \"%s\" (English char,Chinese char,time char);",buf.user);
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
printf("create_history_table success\n");
return 0;
}
//创建单词表
int create_word_table(sqlite3 **value)
{
sqlite3 *db=*value;
char sql[]="create table if not exists Word_t(word char,meaning char);";
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
*value=db;
printf("create_word_table success\n");
return 0;
}
//删除单词表
int drop_word_table(sqlite3 **value)
{
sqlite3 *db=*value;
char sql[]="drop table Word_t;";
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
*value=db;
printf("drop_word_table success\n");
return 0;
}
//关闭数据库
int close_dictionary_db(sqlite3 **db)
{
if(sqlite3_close(*db)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_close error:%s\n",__LINE__,sqlite3_errmsg(*db));
return -1;
}
printf("sqlite3_close success\n");
return 0;
}
//定义查找历史记录
int do_search_history(sqlite3 **value,msg_t buf,int newfd,char *user)
{
sqlite3 *db=*value;
if(buf.code=='S')
{
//准备sql语句
char sql[128]="";
sprintf(sql,"select * from \"%s\" ;",user);
char **res; //接收表结果
int rows; //行号
int cols; //列号
char *errmsg=NULL;//错误信息
//调用函数,获取sql语句后的结果
if(sqlite3_get_table(db,sql,&res,&rows,&cols,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec error:%s\n",sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
for(int i=1;i<rows+1;i++) //外行
{
for(int j=0;j<cols;j++)
{
bzero(buf.msg,sizeof(buf.msg));
sprintf(buf.msg,"%s",res[i*cols+j]);
if(send(newfd,buf.msg,sizeof(buf.msg),0)<0)
{
ERR_MSG("send");
}
}
}
if(send(newfd,"Q",1,0)<0)
{
ERR_MSG("send");
}
//将表释放
sqlite3_free_table(res);
res=NULL;
}
return 0;
}
//定义查找用户
int do_search_user(sqlite3 *db,msg_t buf)
{
int flag=0;
if(buf.code=='E'||buf.code=='L')
{
//准备sql语句
char sql[]="select * from User_t;";
char **res; //接收表结果
int rows; //行号
int cols; //列号
char *errmsg=NULL;//错误信息
//调用函数,获取sql语句后的结果
if(sqlite3_get_table(db,sql,&res,&rows,&cols,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec error:%s\n",sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
for(int i=1;i<rows+1;i++) //外行
{
for(int j=0;j<cols;j+=2)
{
if(strcmp(buf.user,res[i*cols+j])==0)
{
//1:用户名已注册
flag=1;
}
}
}
//将表释放
sqlite3_free_table(res);
res=NULL;
}
return flag;
}
//定义查找密码
int do_search_pass(sqlite3 *db,msg_t buf)
{
int flag=0;
if(buf.code=='L')
{
//准备sql语句
char sql[]="select * from User_t;";
char **res; //接收表结果
int rows; //行号
int cols; //列号
char *errmsg=NULL;//错误信息
//调用函数,获取sql语句后的结果
if(sqlite3_get_table(db,sql,&res,&rows,&cols,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec error:%s\n",sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
for(int i=1;i<rows+1;i++) //外行
{
for(int j=1;j<cols;j+=2)
{
if(strcmp(buf.passwd,res[i*cols+j])==0)
{
//1:密码正确
flag=1;
}
}
}
//将表释放
sqlite3_free_table(res);
res=NULL;
}
return flag;
}
//定义查找单词功能
void do_search_word(sqlite3 **value,msg_t buf,char *user,int newfd)
{
sqlite3 *db = *value;
if(buf.code=='F')
{
//准备sql语句
char sql[]="select * from Word_t;";
char **res; //接收表结果
int rows; //行号
int cols; //列号
char *errmsg=NULL;//错误信息
//调用函数,获取sql语句后的结果
if(sqlite3_get_table(db,sql,&res,&rows,&cols,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec error:%s\n",sqlite3_errmsg(db));
sqlite3_free(errmsg);
}
for(int i=1;i<rows+1;i++) //外行
{
for(int j=0;j<cols;j+=2)
{
if(strcmp(buf.msg,res[i*cols+j])==0)
{
strcpy(buf.msg,res[i*cols+j+1]);
printf("%d\n",__LINE__);
puts(user);
do_add_history(db,user,res[i*cols+j],res[i*cols+j+1]);
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
sqlite3_free_table(res);
res=NULL;
return;
}
}
}
bzero(buf.msg,sizeof(buf.msg));
strcpy(buf.msg,"word unexist");
if(send(newfd,buf.msg,sizeof(buf.msg),0)==-1)
{
ERR_MSG("send");
}
//将表释放
sqlite3_free_table(res);
res=NULL;
}
return;
}
//添加用户信息
int do_add_user(sqlite3 *db,msg_t buf)
{
//准备sql语句
char sql[128] = "insert into User_t values(user,passwd)";
//功能:将格式串转换为字符串
sprintf( sql,"insert into User_t values(\"%s\",\"%s\");",buf.user,buf.passwd);
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
printf("insert success\n");
return 0;
}
//添加历史信息
int do_add_history(sqlite3 *db,char *user,char *English,char *Chinese)
{
//获取查询时间
time_t t=time(NULL);
struct tm* info=localtime(&t);
char p[128]="";
sprintf(p,"[%4d-%2d-%2d --- %2d:%2d:%2d]",info->tm_year+1900,info->tm_mon+1,\
info->tm_mday,info->tm_hour,info->tm_min,info->tm_sec);
//准备sql语句
char sql[128] = "";
//功能:将格式串转换为字符串
sprintf(sql,"insert into \"%s\" values(\"%s\",\"%s\",\"%s\");",user,English,Chinese,p);
printf("sql = %s\n", sql);//******************
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
printf("insert success\n");
return 0;
}
//添加单词信息
int do_add_word(sqlite3 **value)
{
sqlite3 *db=*value;
char word[128]="",meaning[128]="";
FILE* fp=fopen("./dict.txt","r");
if(NULL==fp)
{
perror("fopen");
return -1;
}
while(1)
{
bzero(word,sizeof(word));
bzero(word,sizeof(meaning));
if(fscanf(fp,"%s",word)==EOF)
{
printf("已读完\n");
break;
}
fgets(meaning,sizeof(meaning),fp);
meaning[strlen(meaning)-1]=0;
//准备sql语句
char sql[128] = "insert into Word_t values(user,passwd)";
sprintf( sql,"insert into Word_t values(\"%s\",\"%s\");",word,meaning);
printf("sql = %s\n", sql);
//定义接收错误信息的指针
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"%d:sqlite3_exec error:%s\n",__LINE__,sqlite3_errmsg(db));
sqlite3_free(errmsg);
return -1;
}
}
*value=db;
printf("insert success\n");
fclose(fp);
return 0;
}
int main(int argc, const char *argv[])
{
//从终端输入地址 端口
if(3!=argc)
{
printf("input error\n");
printf("error: %s <IP><PORT>\n",argv[0]);
return -1;
}
//定义句柄指针
sqlite3 *db=NULL;
//调用创建数据库函数
create_dictionary_db(&db);
//创建用户表
create_user_table(&db);
//创建单词表
create_word_table(&db);
//添加单词信息
do_add_word(&db);//********************
//创建套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
ERR_MSG("socket");
}
printf("socket success\n");
//设置端口号快速重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("setsockopt error");
return -1;
}
printf("端口快速重用成功\n");
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(atoi(argv[2]));
sin.sin_addr.s_addr=inet_addr(argv[1]);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
ERR_MSG("bind");
}
printf("bind success\n");
if(listen(sfd,128)==-1)
{
ERR_MSG("listen");
}
printf("listen success\n");
struct sockaddr_in cin;
cin.sin_family=AF_INET;
socklen_t socklen=sizeof(cin);
//定义线程号
pthread_t tid;
while(1)
{
int newfd=accept(sfd,(struct sockaddr*)&cin,&socklen);
if(newfd==-1)
{
ERR_MSG("accept");
}
printf("新客户端连接,newfd=%d\n",newfd);
//定义传参
struct cli_msg info;
info.newfd =newfd;
info.cin=cin;
info.db=&db;
if(pthread_create(&tid,NULL,deal_cli_msg,&info)!=0)
{
printf("pthread_create error\n");
return -1;
}
pthread_detach(tid);
}
//删除单词表
drop_word_table(&db);
//关闭数据库
close_dictionary_db(&db);
close(sfd);
return 0;
}
cli.c
#include <head.h>
struct ser_msg
{
int cfd;
struct sockaddr_in cin;
};
typedef struct MSG
{
char code;//L:登录,E:注册,F:查询
char user[9];
char passwd[9];
char msg[128];
}msg_t;
void input(msg_t *buf)
{
printf("&buf1=%p\n",&buf);
printf("请输入用户名:");
bzero(&buf->user,sizeof(buf->user));
scanf("%s",buf->user);
getchar();
printf("请输入密码:");
bzero(&buf->passwd,sizeof(buf->passwd));
scanf("%s",buf->passwd);
printf("%s\t %s \n",buf->user,buf->passwd);
return;
}
int main(int argc, const char *argv[])
{
if(3!=argc)
{
printf("input error\n");
printf("error: %s <IP><PORT>\n",argv[0]);
return -1;
}
int cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd==1)
{
ERR_MSG("socket");
}
printf("cfd = %d\n",cfd);
int reuse =1 ;
if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
ERR_MSG("setsockopt");
}
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(atoi(argv[2]));
cin.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(cfd,(struct sockaddr*)&cin,sizeof(cin))==-1)
{
ERR_MSG("connect");
}
printf("connect success\n");
int type=0;
msg_t buf;
while(1)
{
system("clear");
printf("****************\n");
printf("*****1.注册*****\n");
printf("*****2.登录*****\n");
printf("*****3.退出*****\n");
printf("****************\n");
printf("输入选项:");
scanf("%d",&type);
bzero(buf.msg,sizeof(buf.msg));
fgets(buf.msg,sizeof(buf.msg),stdin);
buf.msg[strlen(buf.msg)-1]='\0';
if(type==1)
{
buf.code='E';
input(&buf);
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
bzero(&buf,sizeof(buf));
int res = recv(cfd,&buf.msg,sizeof(buf.msg),0);
if(res==-1)
{
ERR_MSG("recv");
}
else if(res==0)
{
printf("服务器已经下线\n");
break;
}
printf("server:%s\n",buf.msg);
if(strcmp(buf.msg,"register success")==0)
{
printf("注册成功,请重新登录\n");
continue;
}
else
{
printf("注册失败,请重新注册\n");
continue;
}
}
else if(type==2)
{
buf.code='L';
input(&buf);
printf("&buf2=%p\n",&buf);
printf("buf.user=%s\n",buf.user);
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
bzero(&buf,sizeof(buf));
int res = recv(cfd,&buf.msg,sizeof(buf.msg),0);
if(res==-1)
{
ERR_MSG("recv");
}
else if(res==0)
{
printf("服务器已经下线\n");
break;
}
printf("server:%s\n",buf.msg);
if(strcmp(buf.msg,"login success")==0)
{
while(1)
{
system("clear");
printf("****************\n");
printf("*****1.查找*****\n");
printf("***2.历史记录***\n");
printf("*****3.退出*****\n");
printf("****************\n");
int num=0;
printf("请输入选项:");
scanf("%d",&num);
if(num==1)
{
bzero(buf.msg,sizeof(buf.msg));
buf.code='F';
printf("请输入要找到单词:");
scanf("%s",buf.msg);
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
bzero(&buf,sizeof(buf));
int res = recv(cfd,&buf.msg,sizeof(buf.msg),0);
if(res==-1)
{
ERR_MSG("recv");
}
else if(res==0)
{
printf("服务器已经下线\n");
break;
}
if(strcmp(buf.msg,"word unexist")==0)
{
printf("单词不存在\n");
continue;
}
printf("意思是:%s\n",buf.msg);
}
else if(num==2)
{
int i=0;
bzero(buf.msg,sizeof(buf.msg));
buf.code='S';
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
printf("历史记录:\n");
while(1)
{
bzero(&buf.msg,sizeof(buf.msg));
int res = recv(cfd,&buf.msg,sizeof(buf.msg),0);
if(res==-1)
{
ERR_MSG("recv");
}
if(res==0)
{
printf("服务器已经下线\n");
break;
}
printf("%s ",buf.msg);
++i;
if(i%3==0)
{
puts("");
}
if(strcmp(buf.msg,"Q")==0)
break;
}
}
else if (num==3)
{
bzero(&buf,sizeof(buf));
buf.code='Q';
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
close(cfd);
return 0;
}
}
}
else
{
continue;
}
//break;
}
else if(type==3)
{
bzero(&buf,sizeof(buf));
buf.code='Q';
if(send(cfd,&buf,sizeof(buf),0)==-1)
{
ERR_MSG("send");
}
close(cfd);
return 0;
}
}
return 0;
}