欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在线电子词典

程序员文章站 2022-05-04 14:11:40
...


一、在线电子词典功能

大学生自己编写,如有问题多多指教!

1. 用户登录。
2. 用户注册(已有用户不能注册)。
3. 单词查询(根据客户端输入的单词,服务器可以根据文件查找反馈查询的单词和解释)。
4. 历史记录显示(查询单词时服务器会将历史记录存在数据库中,客户端接收数据库内容)。
5. 可同时登录多个用户。

二、服务器与客户端内容

1.服务器

代码如下(示例):

void create(void);//创建用户
void history(void);//历史记录
void login(void);//登录用户并查询
void query(void);//查询并写入历史记录表
int callback(void *arg,int f_num,char **f_value,char **f_name);//回调函数
sqlite3 *db;//数据库句柄
char name[32]="",password[32]="",sql[128]="";//用户名 密码 数据库执行语句
char *errmsg,num[32]="",num_1[32]="";//报错 页面1选择 页面2选择
int sockfd,acceptfd;//tcp
int ok_1=0;
void handler(int signum);
int main(int argc, const char *argv[])
{
	char buf[128]="";
	int z;
	pid_t pid;
	int s=1;
	if(sqlite3_open("use.db",&db) != 0)//打开数据库
	{
		fprintf(stderr,"sqlite3_open failed: %s\n",sqlite3_errmsg(db));
		exit(-1);
	}
	sqlite3_exec(db,"create table np(name char primary key,password char);",NULL,NULL,&errmsg);
	sqlite3_exec(db,"create table jl(record char,time char);",NULL,NULL,&errmsg);
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd < 0)
	{
		perror("socket failed.");
		exit(-1);
	}
	printf("socket ok.\n");
	struct sockaddr_in serveraddr,clientaddr;
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(8888);                         
	serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

	socklen_t addrlen = sizeof(serveraddr);
	socklen_t clientlen = sizeof(clientaddr);
	int optval = 1;
	socklen_t optval_len = sizeof(optval);
	setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,optval_len);//允许地址重用
	if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
	{
		perror("bind failed.");
		exit(-1); 
	}
	printf("bind ok.\n");


	if(listen(sockfd,8) < 0)
	{
		perror("bind failed.");
		exit(-1);
	}
	printf("listen ok.\n");
#if 1
	signal(SIGCHLD,handler);//注册信号
	while(1)
	{
		acceptfd = accept(sockfd,NULL,NULL);
		printf("acceptfd ok.\n");
		pid = fork();
		if(pid < 0)
		{
			perror("fork failed.");
			exit(-1);
		}
		if(pid == 0)
		{
			close(sockfd);
			while(1)
			{
				z=recv(acceptfd,num,1,0);
				if(z < 0)
				{
					printf("recv failed.\n");
				}
				if(z > 0)
				{
					switch(num[0])
					{
					case '1':create();break;
					case '2':login();break;
					case '3': exit(0);break;
					}
				}
			}
			close(acceptfd);
		}
	}
	return 0;
	}
#endif


/***********************************************************************************/
void create(void)		//创建用户
{
	bzero(num,32);//清空num否则一直进入循环
	ssize_t t,p;
	char cw[32]="The user name already exists";//用户名已存在
	char cg[32]="Creating a successful";//创建成功
	t=recv(acceptfd,name,sizeof(name),0);//接受用户名
	if(t < 0)
	{
		perror("recv err");
		exit(-1);
	}
	p=recv(acceptfd,password,sizeof(password),0);//接受密码
	if(p < 0)
	{
		perror("recv err");
		exit(-1);
	}
	sprintf(sql,"insert into np values(\"%s\",\"%s\");",name,password);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != 0)//写入数据库
	{
		send(acceptfd,cw,sizeof(cw),0);//返回用户名存在
		printf("%s\n",cw);
		fprintf(stderr,"create failed %s\n",errmsg);
	}
	else
	{
		send(acceptfd,cg,sizeof(cg),0);//创建成功
		printf("%s\n",cg);
	}
	bzero(name,32);
	bzero(password,32);
	bzero(sql,128);
}
/*************************************************************************************/
void login(void)//登录用户并查询
{
	bzero(num,32);//清空num否则一直进入循环
	ssize_t t,p;
	int w=1;
	t=recv(acceptfd,name,sizeof(name),0);//接受用户名
	if(t < 0)
	{
		perror("recv err");
		exit(-1);
	}
	p=recv(acceptfd,password,sizeof(password),0);//接受密码
	if(p < 0)
	{
		perror("recv err");
		exit(-1);
	}
	if(sqlite3_exec(db,"select * from np;",callback,"niugewudi",&errmsg) != 0)//回调函数
	{
		fprintf(stderr,"create failed %s\n",errmsg);
		exit(-1);
	}
	if(ok_1==1)
	{
		while(w)
		{
			recv(acceptfd,num_1,sizeof(num_1),0);
			switch(num_1[0])
			{                           
			case '1':query();break;
			case '2':history();break;
			case '3':w=0;break;
			}

		}
	}
}
/*****************************************************************************/
int callback(void *arg,int f_num,char **f_value,char **f_name)//回调函数
{
	int i,j=0;
	char ok[32]="ok",no[32]="no";
	char *sp=NULL,*fp=NULL;
	sp=f_value[0];//用户名
	fp=f_value[1];//密码
	if(strcmp(name,sp) == 0)//比较用户名
	{
		if(strcmp(password,fp)==0)//比较密码
		{
			ok_1=1;
			send(acceptfd,ok,sizeof(ok),0);
			printf("login successfully\n");//登录成功!!!!
		}
		else
		{
			ok_1=0;
			send(acceptfd,no,sizeof(no),0);
			printf("password error\n");//密码错误
		}
	}
	return 0;
}
/****************************************************************************/
void query(void)//查询并写入历史记录表
{
	bzero(num_1,32);
	FILE *tp;//打开文件流指针
	tp=fopen("./1.txt","r");
	char jl[32]="",jl_time[128]="",jl_yj[128]="",cx[128]="",cx_r[128]="",as[128]="                 ";
	time_t t;
	struct tm *sp=NULL;
	recv(acceptfd,jl,sizeof(jl),0);//输入的单词
	strncpy(as,jl,strlen(jl));
	t=time(&t);
	sp=localtime(&t);
	sprintf(jl_time,"%d-%d-%d,%d:%d:%d",sp->tm_year+1900,\
			sp->tm_mon+1,sp->tm_mday,sp->tm_hour,\
			sp->tm_min,sp->tm_sec);
	printf("%s  %s\n",jl,jl_time);
	sprintf(jl_yj,"insert into jl values(\"%s\",\"%s\");",jl,jl_time);
	if(sqlite3_exec(db,jl_yj,NULL,NULL,&errmsg) != 0)//历史记录,时间写入数据库
	{
		fprintf(stderr,"create failed %s\n",errmsg);
	}
	while(fgets(cx,128,tp)!=NULL)
	{
		if(strncmp(as,cx,strlen(as))==0)
		{
			strcpy(cx_r,cx);
			break;
		}
		else
		{
			strcpy(cx_r,"No word was found");
		}
		bzero(cx,128);
	}	
	send(acceptfd,cx_r,sizeof(cx_r),0);
}
/************************************************************************************/
void history(void)
{
	bzero(num_1,32);
	char **resultp;
	int nrow;
	int ncolumn;
	sqlite3_get_table(db,"select * from jl;",&resultp,&nrow,&ncolumn,&errmsg);

	int i,j,sum= 0;
	char ppp[128]="";
	for(i = 0;i < nrow + 1;i++)
	{
		for(j = 0;j < ncolumn;j++)
		{
			sprintf(ppp,"%s",resultp[sum++]);
			printf("%s\n",ppp);
			send(acceptfd,ppp,sizeof(ppp),0);
		}
	}
	strcpy(ppp,"tuichu"); 
	send(acceptfd,ppp,sizeof(ppp),0);
}
/*************************************************************************************/
void handler(int signum)             
{
	waitpid(-1,NULL,WNOHANG);//非阻塞
	printf("signum = %d\n",signum);
}

2.客户端

代码如下(示例):

void create(void);//创建用户
void query(void);//查询并写入历史记录
void login(void);//登录用户并查询
void history(void);//历史记录
int sockfd;
char num[32]="";
char num_1[32]="";
int main(int argc, const char *argv[])
{
	char buf[128] = {0};
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd < 0){
		perror("socket failed.");
		exit(-1);
	}
	printf("socket ok.\n");

	struct sockaddr_in serveraddr;
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

	socklen_t addrlen = sizeof(serveraddr);


	if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
	{
		perror("connect failed.");
		exit(-1);
	}
	printf("connect ok.\n");

	while(1)
	{
		printf("**************************************************\n");
		printf("*  1.创建用户      2.登录用户并查询      3.退出  *\n");
		printf("**************************************************\n");
		printf("please choose:");
		fgets(num,32,stdin);
		num[strlen(num)-1]='\0';
		send(sockfd,num,1,0);
		switch(num[0])
		{
		case '1':create();break;
		case '2':login();break;
		case '3':return 0;break;
		}

	}
	close(sockfd);
	return 0;
}
/********************************************************************************/
void create(void)		//创建用户
{
	bzero(num,32);//清空num否则一直进入函数
	char name[32]="",password[32]="",jg[32]="";
	printf("Input name:");
	fgets(name,32,stdin);//输入用户名
	name[strlen(name)-1]='\0';//!!!!!!!!
	printf("Input password:");
	fgets(password,32,stdin);//输入密码
	password[strlen(password)-1]='\0';//!!!!!!!!!!
	send(sockfd,name,sizeof(name),0);//发送用户名
	send(sockfd,password,sizeof(password),0);//发送密码
	recv(sockfd,jg,sizeof(jg),0);
	printf("%s\n",jg);
}
/*******************************************************************************/
void login(void)//登录用户并查询
{
	bzero(num,32);//清空num否则一直进入函数
	char name[32]="",password[32]="",zq[32]="";
	int w=1;
	printf("Input name:");
	fgets(name,32,stdin);//输入用户名
	name[strlen(name)-1]='\0';//!!!!!!!!
	printf("Input password:");
	fgets(password,32,stdin);//输入密码
	password[strlen(password)-1]='\0';//!!!!!!!!!!
	send(sockfd,name,sizeof(name),0);//发送用户名
	send(sockfd,password,sizeof(password),0);//发送密码
	recv(sockfd,zq,sizeof(zq),0);
	while(w)
	{
		if(zq[0] == 'o')
		{
			printf("login successfully\n");
			printf("**************************************************\n");
			printf("*  1.查询      2.历史记录          3.quit        *\n");
			printf("**************************************************\n");
			printf("please choose:");
			fgets(num_1,32,stdin);
			send(sockfd,num_1,sizeof(num_1),0);
			switch(num_1[0])
			{
			case '1':query();break;
			case '2':history();break;
			case '3':w=0;break;
			}

		}
		else
		{
			printf("No such user\n");//没用该用户
			break;
		}
	}
}
/******************************************************************************/
void query(void)//查找函数
{
	char jl[32]="",cx[128]="";
	printf("Input word : ");
	fgets(jl,32,stdin);//输入的单词
	jl[strlen(jl)-1]='\0';
	send(sockfd,jl,sizeof(jl),0);
	recv(sockfd,cx,sizeof(cx),0);
	if(cx[0]!='N')
	{
		printf("%s\n",cx+17);
	}
	else
	{
		printf("%s\n",cx);
	}

}
/************************************************************************/
void history(void)//历史记录
{
	bzero(num_1,32);
	char ppp[128]="";
	int p=0;
	while(1)
	{
		recv(sockfd,ppp,sizeof(ppp),0);
		if(strcmp(ppp,"tuichu")==0)
		{
			break;
		}
		printf("%-10s",ppp);
		p++;
		if(p%2==0)
		{
			putchar(10);
		}
	}
	p=0;
}

总结

Linux下实现程序设计,基于C语言,利用TCP协议和多进程及Sqlite3数据库,实现多个客户端连接服务器,并实现用户注册登录、英译汉、显示查询历史记录等操作。
———————————————————
具体文件提取
百度网盘链接:https://pan.baidu.com/s/1sx0otIXcKsgUa2DIaY17Mg
提取码:1111