在线电子词典


一、在线电子词典功能

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

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

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值