基于linux系统,实现在线词典的功能
1.注册:用户名注册
2.登录:用户名或密码错误需重新登录
3.查询:输入要查的单词,#键结束查询
5.退出:退出在线词典
软件平台:linux系统,数据库
数据库保存信息
客户端向服务器发送请求,
服务器向客户端返回查询信息
定义数据库中表的结构;
定义消息结构体;
分析服务器端和客户端 流程;
编码实现;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DATABASE “my.db”
//定义结构体
typedef struct
{
int type;
char name[32];
char data[256];
}MSG;
//数据库回调函数
int do_client(int acceptfd,sqlite3 *db);
int do_enroll(int acceptfd,MSG *msg,sqlite3 *db);
int do_login(int acceptfd,MSG *msg,sqlite3 *db);
int do_inquire(int acceptfd,MSG *msg,sqlite3 *db);
int do_searchword(int acceptfd,MSG *msg,char word[]);
int get_date(char *date);
int main(int argc, const char *argv[])
{
int sockfd;
struct sockaddr_in serveraddr;
int n,i;
MSG msg;
sqlite3 *db;
int acceptfd;
pid_t pid;
//打开数据库
if(sqlite3_open(DATABASE,&db) != SQLITE_OK)
{
printf("%s\n",sqlite3_errmsg(db));
exit(-1);
}
else
{
printf("数据库打开成功!");
}
//socket
int serfd = socket(AF_INET, SOCK_STREAM, 0);
if(serfd < 0)
{
puts("socket error.");
return -1;
}
puts("socket success.");
//bind
int ret = -1;
struct sockaddr_in myser;
int perrlen = sizeof(struct sockaddr);
memset(&myser, 0, sizeof(myser));
myser.sin_family = AF_INET;
myser.sin_port = htons(7777);
myser.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(serfd, (struct sockaddr *)&myser, sizeof(myser));
if(ret != 0)
{
puts("bind error.");
close(serfd);
return -1;
}
puts("bind success.");
//listen
ret = listen(serfd, 5);
if(ret != 0)
{
puts("listen error.");
close(serfd);
return -1;
}
puts("listen success.");
//accept
while(1)
{
int connfd = -1;
struct sockaddr_in mycli;
int len = sizeof(mycli);
connfd = accept(serfd, (struct sockaddr *)&mycli, &len);
if(connfd < 0)
{
puts("accept client error.");
close(serfd);
return -1;
}
puts("accept success");
signal(SIGCHLD,SIG_IGN);
if((pid = fork()) < 0)
{
perror("fork");
exit(-1);
}
else if(pid == 0)
{
//处理客户端具体的消息
close(sockfd);
do_client(acceptfd,db);
}
else
{
close(acceptfd);
}
}
close(sockfd);
return 0;
}
int do_client(int acceptfd,sqlite3 *db)
{
MSG msg;
//阻塞接收
while(recv(acceptfd,&msg,sizeof(msg),0) < 0)
{
switch(msg.type)
{
case 1:
do_enroll(acceptfd,&msg,db);
break;
case 2:
if(1 == do_login(acceptfd,&msg,db))
{
do_client(acceptfd,db);
}
break;
case 3:
do_inquire(acceptfd,&msg,db);
break;
define:
printf(“错误的输入!\n”);
}
}
printf(“客户端已退出!\n”);
close(acceptfd);
exit(0);
return 0;
}
int do_enroll(int acceptfd,MSG *msg,sqlite3 *db)
{
char *errmsg;
char sql[128];
printf("%s\n",sql);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
strcpy(msg->data,"用户已存在!");
}
else
{
printf("用户注册成功!");
strcpy(msg->data,"成功!");
}
if(send(acceptfd,msg,sizeof(MSG),0) < 0)
{
perror("send");
exit(-1);
}
return 0;
}
int do_login(int acceptfd,MSG *msg,sqlite3 *db)
{
char sql[128] = {0};
char *errmsg;
int nrow;
int ncloumn;
char **resultp;
memset(sql,0,sizeof(sql));
if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg) != 0)
{
printf("%s\n",errmsg);
exit(-1);
}
else
{
printf("get_table ok!\n");
}
//查询结果处理
if(nrow == 1)
{
sprintf(msg->data,"成功!");
if (send(acceptfd,msg,sizeof(MSG),0) < 0)
{
perror("send");
}
return 1;
}
else
{
sprintf(msg->data,"用户名/密码 错误!");
}
send(acceptfd,msg,sizeof(MSG),0);
}
int do_searchword(int acceptfd,MSG *msg,char word[])
{
FILE *fp;
int len = 0;
char temp[512] = {0};
int result;
char *p;
//打开文件,读取文件,进行比对
if((fp = fopen("dict.txt","r")) == NULL)
{
perror("fopen");
strcpy(msg->data,"字典文件打开失败");
if(send(acceptfd,msg,sizeof(MSG),0) < 0)
{
perror("send");
exit(-1);
}
return 0;
}
//打印出客户端需要查询的单词以及长度
len = strlen(word);
printf("%s,len = %d\n ",word,len);
//读文件,查询单词
while(fgets(temp,512,fp) != NULL)
{
result = strncmp(temp,word,len);
if(result < 0 )
{
continue;
}
else if(result > 0 )
{
break;
}
else if(result == 0 && temp[len] !=' ')
{
break;
}
else
{
//找到所查询的单词
//p跳过中间空格,指向注释
strcpy(msg->data,p);
//将注释提取出来
fclose(fp);
return 1;
}
}
fclose(fp);
fp = NULL;
return 0;
}
int get_date(char *date)
{
time_t t;
struct tm *tp;
time(&t);
//时间格式转换
tp = localtime(&t);
sprintf(date,"%d-%d-%d %d:%d:%d",tp->tm_year + 1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);
return 0;
}
int do_inquire(int acceptfd,MSG *msg,sqlite3 *db)
{
char word[64];
int found = 0;
char date[128];//存放查询时间
char sql[128];
char *errmsg;
//取出MSG中要查询的单词
strcpy(word,msg->data);
found = do_searchword(acceptfd,msg,word);
//找到,查询记录存储到表中
if(found == 1)
{
//需要获取系统时间
get_date(date);
sprintf(sql,"insert into record values('%s','%s','%s');",msg->name,date,word);
//printf("%s\n",sql);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
printf("%s\n",errmsg);
return -1;
}
}
else
{
strcpy(msg->data,"没有找到这个单词的解释!");
}
//查询结果返回
if(send(acceptfd,msg,sizeof(MSG),0) < 0)
{
perror("send");
exit(-1);
}
return 1;
}