网络编程-在线词典(服务器端)

一、项目名称:在线词典

二、项目需求

基于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;

}

你可能感兴趣的:(网络,数据库)