电子词典项目

ser.c:

#include <stdio.h>                                                               
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sqlite3.h>

struct msg
{
	int sfd_new;
	struct sockaddr_in cin;
	sqlite3* db;
};

int tcpini(struct msg);
void* rcvsend(void* arg);
int cidian(sqlite3* db);
int enroll(int sfd_new,sqlite3* db,char buf[]);
int login(int sfd_new,sqlite3* db,char buf[],char **user);
int inquire(int sfd_new,sqlite3* db,char buf[],char user[]);
int history(int sfd_new,sqlite3* db,char buf[],char user[]);
int quit(int sfd_new,sqlite3* db,char user[]);

int main(int argc, const char *argv[])
{

	sqlite3* db=NULL;
	if(sqlite3_open("./my.db",&db)!=SQLITE_OK)
	{   
		fprintf(stderr,"line:%d  sqlite3_open:%s\n",__LINE__,sqlite3_errmsg(db));
		return -1; 
	}   
	printf("database open success\n");
	cidian(db);//导入词库

	struct msg temp;
	temp.db=db;
	tcpini(temp);//tcp多线程服务器
	
	return 0;
}

int cidian(sqlite3* db)
{
	//创建一个word表格
	char sql[128]="create table word (wordname char,mean char)";
	char* errmsg=NULL;
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{   
		if(sqlite3_errcode(db)==1)
		{
			printf("表格已存在,无需再次导入\n");
			return 0;
		}
		fprintf(stderr,"line:%d  sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1; 
	}   
	printf("create word table success\n");

	//导入单词
	FILE *fd=fopen("./111.txt","r");    
	char res[512]="";
	char word[32]="";
	char mean[256]="";
	char *p=NULL;
	printf("<<<导入词库中>>>\n");
	while(fgets(res,100,fd)!=NULL)
	{   
		res[strlen(res)-1] = 0;
		p=res;
		while(*p!=' '||*(p+1)!=' ')
		{
			p++;
		}   
		*p='\0';
		strcpy(word,res);
		strcpy(mean,p+3);                                                                  

		sprintf(sql,"insert into word values(\"%s\",\"%s\")",word,mean);
		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
		{
			fprintf(stderr,"line:%d  sqlite3_exec:%s\n",__LINE__,errmsg);
			return -1;
		}

	}
	printf("导入成功\n");

/*	//关闭数据库
	if(sqlite3_close(db)!=SQLITE_OK)
	{
		fprintf(stderr,"line:%d  sqlite3_close:%s\n",__LINE__,sqlite3_errmsg(db));
		fprintf(stderr,"line:%d  sqlite3_close:%s\n",__LINE__,sqlite3_errmsg(db));
		return -1;
	}
	printf("database close success\n");*/

	return 0;
}

int tcpini(struct msg temp)
{
	//套接字
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		perror("sfd");
		return -1;
	}
	//允许端口快速被重用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
	{
		perror("setsockopt");
		return -1;
	}

	//bind绑定
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(8888);
	sin.sin_addr.s_addr=inet_addr("192.168.10.182");
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		perror("bind");
		return -1;
	}

	//listen
	if(listen(sfd,128)<0)
	{
		perror("listen");
		return -1;
	}
	printf("服务器监听成功\n");
	//accept

	struct sockaddr_in cin;
	socklen_t len=sizeof(cin);
	pid_t pid;
	int sfd_new=0;
	struct msg info;
	while(1)
	{
		sfd_new=accept(sfd,(struct sockaddr*)&cin,&len);
		if(sfd_new<0)
		{
			perror("accept");
			return -1;
		}
		printf("[%s:%d] newfd = %d 连接成功\n", \
				inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), sfd_new);

		info.sfd_new=sfd_new;
		info.cin=cin;
		info.db=temp.db;
		//线程
		pthread_t pid;
		//recv
		if(pthread_create(&pid,NULL,rcvsend,(void*)&info)<0)
		{
			perror("pthread_create");
			return -1;
		}
		//分离线程
		pthread_detach(pid);
	}
	
	close(sfd);
	return 0;
}

void* rcvsend(void* arg)//分线程进行交互
{
	char buf[128]="";
	char user[32]="";
	char sql[128]="";
	char *p=user;
	char *errmsg=NULL;
	ssize_t res=0;
	int sfd_new=((struct msg*)arg)->sfd_new;
	struct sockaddr_in cin=((struct msg*)arg)->cin;
	while(1)
	{
		//接收客户端请求
		bzero(buf,sizeof(buf));
		res=recv(sfd_new,buf,sizeof(buf),0);
		if(res==0)
		{
			printf("客户端关闭\n");
			//取消该客户端登录信息
			sprintf(sql,"UPDATE user SET flag='0' WHERE name='%s';",user);
			if(sqlite3_exec(((struct msg*)arg)->db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
			{
				fprintf(stderr,"line:%d  sqlite3_exec:%s  error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(((struct msg*)arg)->db));
				pthread_exit(NULL);
			}
			break;
		}
		else if(res<0)
		{
			perror("recv");
			break;
		}
		
		//判断操作码 1.注册 2.登录 3.查询 4.历史记录 5.退出登录

		if(1==buf[0])
		{
			printf("注册\n");
			enroll(sfd_new,((struct msg*)arg)->db,buf);
		}
		else if(2==buf[0])
		{
			printf("登录\n");
			login(sfd_new,((struct msg*)arg)->db,buf,&p);
		}
		else if(3==buf[0])//查询
		{
			inquire(sfd_new,((struct msg*)arg)->db,buf,user);
		}
		else if(4==buf[0])
		{
			history(sfd_new,((struct msg*)arg)->db,buf,user);
		}
		else if(5==buf[0])
		{
			quit(sfd_new,((struct msg*)arg)->db,user);//退出登录,登录状态置0
		}
	}
	close(sfd_new);
	pthread_exit(NULL);
}

int enroll(int sfd_new,sqlite3* db,char buf[])
{
	char sql[128]="";
	char* errmsg=NULL;
	char name[32]="";
	char passwd[32]="";

	strcpy(name,buf+1);
	strcpy(passwd,buf+1+strlen(name)+1);
	//创建一个user表格
	bzero(sql,sizeof(sql));
	strcpy(sql,"create table if not exists user (name char PRIMARY KEY,passwd char,flag char)");
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{   
		fprintf(stderr,"line:%d  sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1; 
	}
	//插入用户信息
	sprintf(sql,"insert into user values(\"%s\",\"%s\",'0')",name,passwd);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{
		if(sqlite3_errcode(db)==19)
		{
			sprintf(sql,"%c%s",0,"Registration failed with duplicate username");
			if(send(sfd_new,sql,sizeof(sql),0)<0)
			{
				perror("send");
				return -1;
			}
		}
		fprintf(stderr,"line:%d  sqlite3_exec:%s  error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
		return -1;
	}
	sql[0]=1;
	if(send(sfd_new,sql,sizeof(sql),0)<0)
	{
		perror("send");
		return -1;
	}
	return 0;
}

int login(int sfd_new,sqlite3* db,char buf[],char **user)//登录
{
	//取出用户名和密码
	char sql[128]="";
	char* errmsg=NULL;
	char name[32]="";
	char passwd[32]="";
	strcpy(name,buf+1);
	strcpy(passwd,buf+1+strlen(name)+1);
	//判断对与否
	sprintf(sql,"select * from user where name='%s';",name);
	char **result=NULL;
	if(sqlite3_get_table(db,sql,&result,NULL,NULL,&errmsg)!=0)
	{
		fprintf(stderr,"line:%d  sqlite3_get_table:%s\n",__LINE__,errmsg);
	}
	if(*result==NULL)//判断用户名是否存在
	{
		sprintf(sql,"%c%s",0,"The user name does not exist");
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
		}
		return -1;
	}
	if(strcmp(*(result+4),passwd)!=0)//判断密码是否正确              
	{
		sprintf(sql,"%c%s",0,"The password is incorrect");
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
		}
		return -1;
	}
	//账号密码正确,判断登录状态
	if(*(result+5)[0]=='0')
	{
		sql[0]=1;
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
			return -1;
		}	
	}
	else
	{
		sprintf(sql,"%c%s",0,"Login failed, repeated login");
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
		}
		return -1;
	}
	strcpy(*user,name);//登录成功,保存用户名
	//登录状态置1
	sprintf(sql,"UPDATE user SET flag='1' WHERE name='%s';",name);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr,"line:%d  sqlite3_exec:%s  error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
		return -1;
	}
	return 0;
}

int inquire(int sfd_new,sqlite3* db,char buf[],char user[])//查询
{
	char sql[128]="";
	char* errmsg=NULL;
	char word[32]="";
	int row,column;
	time_t t;
	struct tm* info=NULL;
	char h_time[128]="";
	//取出word
	strcpy(word,buf+1);

	//创建一个history表格
	bzero(sql,sizeof(sql));
	sprintf(sql,"create table if not exists %s_history (word char,mean char,time char)",user);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{   
		fprintf(stderr,"line:%d  sqlite3_exec:%s\n",__LINE__,errmsg);
		return -1; 
	}
	
	sprintf(sql,"select * from word where wordname=\"%s\";",word);
	char **result=NULL;
	if(sqlite3_get_table(db,sql,&result,&row,&column,&errmsg)!=0)
	{
		fprintf(stderr,"line:%d  sqlite3_get_table:%s\n",__LINE__,errmsg);
	}
	if(*result==NULL)//没有单词
	{
		sprintf(sql,"%c%s%c",0,"The word does not exist",0);
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
		}
		return -1;
	}
	//发送单词意思,插入历史记录
	bzero(sql,sizeof(sql));
	int i = 0;
	for(i=3; i<(row+1)*column; i+=2)
	{
		bzero(sql,sizeof(sql));
		sprintf(sql,"%c%s%c",1,*(result+i),0);
		if(send(sfd_new,sql,sizeof(sql),0)<0)//发送单词
		{
			perror("send");
			return -1;
		}

		t=time(NULL);
		info=localtime(&t);
		sprintf(h_time,"%d-%02d-%02d-%02d-%02d-%02d%c",info->tm_year+1900,\
				info->tm_mon+1, info->tm_mday, info->tm_hour,\
				info->tm_min, info->tm_sec,0);
		sprintf(sql,"insert into %s_history values(\"%s\",\"%s\",'%s')",user,word,*(result+i),h_time);
		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
		{
			fprintf(stderr,"line:%d  sqlite3_exec:%s  error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
			return -1;
		}
	}
	sprintf(sql,"%c",2);
	if(send(sfd_new,sql,sizeof(sql),0)<0)
	{
		perror("send");
		return -1;
	}

	return 0;
}

int history(int sfd_new,sqlite3* db,char buf[],char user[])
{
	char sql[128]="";
	char* errmsg=NULL;
	int row,column;

	sprintf(sql,"select * from %s_history;",user);
	char **result=NULL;
	if(sqlite3_get_table(db,sql,&result,&row,&column,&errmsg)!=0)
	{
		fprintf(stderr,"line:%d  sqlite3_get_table:%s\n",__LINE__,errmsg);
	}
	if(*result==NULL)//没有记录
	{
		sprintf(sql,"%c%s%c",0,"The history table is empty",0);
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
		}
		return -1;
	}
	//发送每一条历史记录
	bzero(sql,sizeof(sql));
	int i = 0;
	for(i=3; i<(row+1)*column; i+=3)
	{
		bzero(sql,sizeof(sql));
		sprintf(sql,"%c%s\t%s\t%s%c",1,*(result+i),*(result+i+1),*(result+i+2),0);
		if(send(sfd_new,sql,sizeof(sql),0)<0)
		{
			perror("send");
			return -1;
		}
	}	
	sprintf(sql,"%c",2);
	if(send(sfd_new,sql,sizeof(sql),0)<0)
	{
		perror("send");
		return -1;
	}
}

int quit(int sfd_new,sqlite3* db,char user[])
{
	char sql[128]="";
	char *errmsg=NULL;

	//取消该客户端登录信息
	sprintf(sql,"UPDATE user SET flag='0' WHERE name='%s';",user);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{
		fprintf(stderr,"line:%d  sqlite3_exec:%s\n",__LINE__,errmsg);
		pthread_exit(NULL);
	}

	sprintf(sql,"%c",2);
	if(send(sfd_new,sql,sizeof(sql),0)<0)
	{
		perror("send");
		return -1;
	}

}

cil.c:

#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int cilini(int* sfd);
int page1(int sfd);
int enroll(int sfd);
int login(int sfd);
int page2(int sfd);
int inquire(int sfd);
int history(int sfd);
int quit(int sfd);



int main(int argc, const char *argv[])
{
	int sfd=0;
	cilini(&sfd);

	page1(sfd);//注册登录页面

	//关闭文件描述符
	close(sfd);
	return 0;
}


int cilini(int* sfd)
{
	//创建报式套接字
	*sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd < 0)
	{
		perror("socket");
		return -1;
	}

	//填充服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;     
	sin.sin_port=htons(8888); 
	sin.sin_addr.s_addr=inet_addr("192.168.10.182"); 

	//connect
	if(connect(*sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		perror("connect");
		return -1;
	}
	printf("服务器连接成功\n");
}

int page1(int sfd)
{
	char c = 0;
	while(1)
	{
		system("clear");
		printf("**************************\n");
		printf("*******1.  注册  *********\n");
		printf("*******2.  登录  *********\n");
		printf("*******3.  退出  *********\n");
		printf("**************************\n");
		printf("请输入>>>");

		c = getchar();
		while(getchar()!=10);

		switch(c)
		{
		case '1':
			enroll(sfd);
			break;
		case '2':
			login(sfd);
			break;
		case '3':
			return 0;
		default:
			printf("输入错误,请重新输入\n");
		}

		printf("输入任意字符回车清屏>>>");
		while(getchar() !=10);
	}
	return 0;
}


int enroll(int sfd)
{
	char buf[128]="";
	char name[32] = "";
	char passwd[32] = "";

	bzero(name, sizeof(name));
	printf("请输入用户名>>>");
	fgets(name, sizeof(name), stdin);
	name[strlen(name)-1] = 0;
	bzero(passwd, sizeof(passwd));
	printf("请输入密码>>>");
	fgets(passwd, sizeof(passwd), stdin);
	passwd[strlen(passwd)-1] = 0;

	//注册请求包
	bzero(buf,sizeof(buf));
	int size = sprintf(buf, "%c%s%c%s%c",1,name,0,passwd,0);
	if(send(sfd, buf, size, 0) < 0)
	{
		perror("send");
		return -1;
	}
	if(recv(sfd,buf,sizeof(buf),0)<0)
	{
		perror("recv");
		return -1;
	}
	if(buf[0]==1)
	{
		printf("%s注册成功\n",name);
	}
	else
	{
		printf("!!!!!!!!!!!!!!!!!!\n");
		printf("%s\n",buf+1);
		printf("!!!!!!!!!!!!!!!!!!\n");
	}
	return 0;
}

int login(int sfd)
{
	char buf[128]="";
	char name[32] = "";
	char passwd[32] = "";

	bzero(name, sizeof(name));
	printf("请输入用户名>>>");
	fgets(name, sizeof(name), stdin);
	name[strlen(name)-1] = 0;
	bzero(passwd, sizeof(passwd));
	printf("请输入密码>>>");
	fgets(passwd, sizeof(passwd), stdin);
	passwd[strlen(passwd)-1] = 0;
	
	//登录请求包
	bzero(buf,sizeof(buf));
	int size = sprintf(buf, "%c%s%c%s%c",2,name,0,passwd,0);
	if(send(sfd, buf, size, 0) < 0)
	{
		perror("send");
		return -1;
	}
	if(recv(sfd,buf,sizeof(buf),0)<0)
	{
		perror("recv");
		return -1;
	}
	if(buf[0]==1)
	{
		page2(sfd);
	}
	else
	{
		printf("!!!!!!!!!!!!!!!!!!\n");
		printf("%s\n",buf+1);
		printf("!!!!!!!!!!!!!!!!!!\n");
	}
	return 0;
}

int page2(int sfd)
{
	char c = 0;
	while(1)
	{
		system("clear");
		printf("**************************\n");
		printf("*******1.  查询  *********\n");
		printf("*******2.历史记录*********\n");
		printf("*******3.  退出  *********\n");
		printf("**************************\n");
		printf("请输入>>>");

		c = getchar();
		while(getchar()!=10);

		switch(c)
		{
		case '1':
			inquire(sfd);//查询
			break;
		case '2':
			history(sfd);
			break;
		case '3':
			quit(sfd);
			return 0;
			break;
		default:
			printf("输入错误,请重新输入\n");
		}

		printf("输入任意字符回车清屏>>>");
		while(getchar() !=10);
	}
	return 0;
}

int inquire(int sfd)
{
	char buf[128]="";
	char word[32]="";

	bzero(buf,sizeof(buf));
	printf("请输入要查询的单词>>>");
	fgets(word, sizeof(word), stdin);
	word[strlen(word)-1] = 0;
	//查询请求包
	bzero(buf,sizeof(buf));
	int size = sprintf(buf, "%c%s%c",3,word,0);
	if(send(sfd, buf, size, 0) < 0)
	{
		perror("send");
		return -1;
	}
	while(1)
	{
		bzero(buf,sizeof(buf));
		if(recv(sfd,buf,sizeof(buf),0)<0)
		{
			perror("recv");
			return -1;
		}
		if(buf[0]==1)
		{
			printf("%s\t%s\n",word,buf+1);
		}
		else if(buf[0]==0)
		{
			printf("!!!!!!!!!!!!!!!!!!\n");
			printf("%s\n",buf+1);
			printf("!!!!!!!!!!!!!!!!!!\n");
			break;
		}
		else if(buf[0]==2)
		{
			break;
		}
	}
	return 0;	
}

int history(int sfd)
{
	char buf[128]="";
	//查看历史记录请求包
	bzero(buf,sizeof(buf));
	int size = sprintf(buf, "%c",4);
	if(send(sfd, buf, size, 0) < 0)
	{
		perror("send");
		return -1;
	}
	while(1)
	{
		bzero(buf,sizeof(buf));
		if(recv(sfd,buf,sizeof(buf),0)<0)
		{
			perror("recv");
			return -1;
		}
		if(buf[0]==1)
		{
			printf("%s\n",buf+1);
		}
		else if(buf[0]==0)
		{
			printf("!!!!!!!!!!!!!!!!!!\n");
			printf("%s\n",buf+1);
			printf("!!!!!!!!!!!!!!!!!!\n");
			return -1;
		}
		else if(buf[0]==2)
		{
			break;
		}
	}	
}

int quit(int sfd)
{
	char buf[128]="";
	//查看历史记录请求包
	bzero(buf,sizeof(buf));
	int size = sprintf(buf, "%c",5);
	if(send(sfd, buf, size, 0) < 0)
	{
		perror("send");
		return -1;
	}

	bzero(buf,sizeof(buf));
	if(recv(sfd,buf,sizeof(buf),0)<0)
	{
		perror("recv");
		return -1;
	}
	if(buf[0]==2)
	{
		printf("退出登录成功\n");
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值