在线词典综合项目

应用综合项目

  • 在线英英词典
  • 项目功能描述
  • 用户注册和登录验证
  • 服务器将历史用户信息保存在数据库中,客户端输入用户名和密码,服务器端在数据库中查询,匹配,返回结果。
  • 单词在线翻译
  • 项目流程
  • 定义数据库中表的结构
  • 定义消息结果体
  • 分析服务器和客户端流程
  • 编写代码
    在这里插入图片描述
client.c

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

#define N 32
#define R  1  //USER-register
#define L  2   //USER-login
#define Q  3   //USER-query
#define H   4   //USER-history

//定义通信双方的信息结构体
typedef struct {
	int type;
	char name[N];
	cahr data[256];
}MSG;


int  do_register(int sockfd,MSG *msg)
{
	msg->type=R;
	printf("input name:");
	scanf("%s",msg->name);
	getchar();
	
	printf("input passwd:");
	scanf("%s",msg->data);
	if(send(sockfd,msg,sizeof(MSG),0)<0)
	{
		printf("fail to send.\n");
		return -1;
	}
	if(recv(sockfd,msg,sizeof(MSG),0)<0)
	{
		printf("fail to revc.\n");
		return -1 ;
	}
	
	//ok or user already exist!
	printf("%s\n"msg->data);
	return 0;
}

int do_login(int sockfd,MSG *msg)
{
	msg->type=L;
	printf("input name:");
	scanf("%s",msg->name);
	getchar();
	
	printf("input passwd:");
	scanf("%s",msg->data);
	
	if(send(sockfd,msg,sizeof(MSG),0)<0)
	{
		printf("fail to send\n");
		exit(1);
	}
	if(recv(sockfd,msg,sizeof(MSG),0)<0)
	{
		printf("fail to recv");
		exit(1);
	}
	if(strncmp(msg->data,"ok",3)==0)
	{
		printf("login ok\n");
		return 1;
	}
	else
	{
		printf("%s\n",msg->data);
	}
	return 0;
	
}

int do_query(int sockfd,MSG *msg)
{
	msg->data=Q;
	puts("------------------------");
	while(1)
	{
		printf("input word:");
		scanf("%s",msg->data);
		getchar();
		//客户端输入“#”号,返回到上一级菜单
		if(strncmp(msg->data,"#",1)==0)
			break;

		//将要查询的单词发送给服务器
		if(send(sockfd,msg,sizeof(MSG),0)<0)
		{
			printf("fail to send.\n");
			return -1;
		}
		//接收服务器返回来的单词的注释
		if(recv(sockfd,msg,sizeof(MSG),0)<0)
		{
			printf("fail to recv.\n");
			return -1;
		}
		printf("%s\n",msg->data);
	}
}

int do_history(int sockfd,MSG *msg)
{
	msg->data='H';
	send(sockfd,msg,sizeof(MSG),0);
	//接收服务器传回来的历史记录信息
	while(1){
		recv(sockfd,msg,sizeof(MSG),0);
		if(msg->data[0]=='\0')
			break;
		//输出历史记录信息
		printf("%s\n",msg->data);
	}
	return 0;
}
//./server 192.168.XXX.XXX 端口号
int main(int argc,char *argv[])
{
	int sockfd;
	struct sockaddr_serveraddr;
	MSG msg;
	int n;
	if(argc!=3)
	{
		printf("usage :%s serverip port.\n",argv[0]);
		return -1;
	}
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("fail to socket.\n");
		return -1;
	}
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_add.s_addr=inet_addr(argc[1]);
	serveraddr.sin_port=htons(argv[2]);
	if(connect(sockfd,struct sockaddr*)*serveraddr,sizeof(serveraddr))<0)
	{
		perror(" fail to connect");
		return -1;
	}
	while(1)
	{
		printf("****************************************\n");
		printf(" *1,register   2,login     3,quit       *\n");
		printf("*****************************************\n");

		printf("please choose:");
		printf("%d",&n);
		getchar();
	
		switch(n)
		{
			case 1:
				do_register(sockfd,&msg);
				break;
			case 2:
				if(do_login(sockfd,&msg)==1)
				{
					goto next;
				}
				break;
			case 3:
				close(sockfd);
				exit(0);
				break;
			default:
				printf("Invaild data cmd.\n");
		}
	}

next:
	while(1)
	{
		printf("**************************************\n");
		printf("1,query_word   2.history_record   3,quit  *\n");
		printf("***************************************\n");
		printf("please choose:");
		scanf("&d",&n);
		getchar();
	
		switch(n)
		{
			case 1:
				do_query(sockfd,&msg);
				break;
			case 2:
				do_history(sockfd,&msg);
				break;
			case 3:
				close(sockfd);
				break;
			}
		}

	return 0;
}
server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<sqlite3.h>
#include<signal.h>
#include<time.h>


#define N 32
#define R  1  //USER-register
#define L  2   //USER-login
#define Q  3   //USER-query
#define H   4   //USER-history

#define DATABAE "my.db"

//定义通信双方的信息结构体
typedef struct {
	int type;
	char name[N];
	cahr data[256];
}MSG;

int do_client(int acceptfd,sqlite3 *db);
void do_register(int acceptfd,MSG *msg,sqlite3 *db);
int do_login(int acceptfd,MSG *msg,sqlite3 *db);
int do_query(int acceptfd,MSG *msg,sqlite3* db);
int do_history(int acceptfd,MSG *msg,sqlite3 *db);
int do_searchword(int acceptfd,MSG *msg,char word[]);
int history_callback(void *arg,int f_num,char ** f_value,char**f_name);
int get_date(char *date);
//./server 192.168.XXX.XXX 端口号
int main(int argc,char *argv[])
{
	int sockfd;
	struct sockaddr_serveraddr;
	MSG msg;
	int n;
	sqlite3 *db;
	int acceptfd;
	pid_t pid;
	if(argc!=3)
	{
		printf("usage :%s serverip port.\n",argv[0]);
		return -1;
	}
	//打开数据库
	if(sqlite3_open(DATABASE,&db)!=SQLITE_OK)
	{
		printf("%s\n",sqlite3_errmsg(db));
		return -1;
			
	}
	else
	{
		printf("open DATABASE succeff.\n");
	}
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("fail to socket.\n");
		return -1;
	}
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_add.s_addr=inet_addr(argc[1]);
	serveraddr.sin_port=htons(argv[2]);
	
	if(bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))<0)
	{
		perror("fail to bind\n");
		return -1;
	}
	//将套接字设为监听模式
	if(listen(sockfd,5)<0)
	{
		printf("fail to listen.\n);
		return -1;
	}

	signal(SIGCHLD,SIG_IGN); //处理僵尸进程
	while(1)
	{
			if((acceptfd=accept(sockfd,NULL,NULL))<0)
			{
				perror("fail to accept");
				reutrn -1;
			}
			if(pid=fork()<0)
			{
				perror("fail to fork");
				return -1;
			}
			else if(pid==0) //儿子进程
			{
				//处理客户端具体的信息
				close(sockfd);
				do_client();
			}
			else  //父进程,用来接收客户端的请求
			{
				close(acceptfd);
			}	
	}
	return 0;
}

int do_client(int acceptfd,sqlite3 *db)
{
	MSG msg;
	while(recv(acceptfd,&msg,sizeof(msg),0)>0)
	{
		printf("type:%d\n",,msg.type);
		switch(msg.type)
		{
			case R:
				do_regitster(acceptfd,&msg,db);
				break;
			case L:
				do_login(acceptfd,&msg,db);
				break;
			case Q:
				do_query(acceptfd,&msg,db);
				break;
			case H:
				do_history(acceptfd,&msg,db);
				break;
			default:
				printf("invalid data msg.\n");
			}
	}
	printf("client exit.\n");
	close(acceptfd);
	exit(0);
	return 0;
}
void do_register(int acceptfd,MSG *msg,sqlite3 *db)
{
	char *errmsg;
	char sql[128];
	sprintf(sql,"insert into usr values('%s','%s');",msg->name,msg->data);
	printf("%s\n".sql);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
	{
		printf("%s\n",errmsg);
		strcpy(msg->data,"usr name already exist.");
	}
	else
	{
		printf("client register ok\n");
		strcpy(msg->data,"ok");
	}
	if(send(acceptfd,msg,sizeof(MSG),0)<0)
	{
		printf("fail to send");
		return -1;
	}
}

int login(int acceptfd,MSG *msg,sqlite3 *db)
{
	char *errmsg;
	char sql[128]={};
	int nrow;
	int ncloumn;
	char ** resultp;
	sprintf(sql,"select *from usr where name='%s'and pass='%s';",msg->name,msg->data);
	printf("%s\n",sql);
	if(sqlite3_get_table(db,sql,&resultp,&nrow,&nclonum,&errmsg)!=SQLITE_OK)
	{
		printf("%s\n",errmsg);
		return -1;
	}
	else
	{
		printf("get_table ok!\n");
	}
	//查询成功数据库中有此用户
	if(nrow=1)
	{
		strcpy(msg->data,"ok);
		send(acceptfd,msg,sizeof(MSG),0)
	}
	else if(nrow=0)
	{
		strcpy(msg->data,"usr/passwd wrong");
		send(acceptfd,msg,sizeof(MSG),0);
		return 1;
	}
	return 0;
}

int do_searchword(int acceptfd,MSG *msg,char word[])
{
	FILE *fp;
	char temp[512]={};
	int result;
	char *p;
	//打开文件,读取文件,进行比对
	if((fp=fopen("dict.txt","r"))==NULL)
	{	
		perror("fail to fopen\n");
		strcpy(msg->data,"failed to open dict.txt");
		send(acceptfd,msg,sizeof(MSG),0);
		return -1;
	}
	//打印出客户端要查询的单词
	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;
		if(result<0||temp[len]!='')
			break;
		//表示找到了查询的单词
		p=temp+len;
		while(*p==' ')
		{
			p++;
		}
		//找到了注释,跳跃过所有的空格
		strcpy(msg->data,p);
		//注释拷贝完后,应该关闭文件
		fclose(fp);
		return 1;
	}
}
int get_date(char *date)
{
	time_t t;
	struct tm *tp;
	time(&t);
	//进行时间格式转化
	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);	
}
int do_query(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 value('%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,"not found!");	
	}
	//将查询的结果发送给客户端
	send(acceptfd,msg,sizeof(MSG),0);
	return 0;
}
//得到查询结果并且需要将历史记录发送给客户端
int history_callback(void *arg,int f_num,char ** f_value,char**f_name)
{
	//record:name,date,word
	int acceptfd;
	MSG msg;
	aceptfd=*((int )arg);
	
	sprintf(msg.data,"%s,%s",f_value[1],f_value[2]);
	send(acceptfd,&msg,sizeof(MSG),0);
	return 0;
}

int do_history(int acceptfd,MSG *msg,sqlite3 *db)
{
	char sql[128]={};
	sprintf(sql,"select *from record where name='%s';",msg->name);
	//查询数据库
	if(sqlite3_exec(db,sql,history_callback,void *)&acceptfd,&errmsg)!=SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		printf("query record done\n");
	}
	//所有的历史信息查询完毕后,给客户端发送结束信息
	msg->data[0]='\0';
	send(acceptfd,msg,sizeof(MSG),0);
	return 0;
}

编译客户端和服务器端程序时,引入sqlite3 库
gcc server.c -o server -lsqlite3
创建数据库:sqlite3 my.db
创建两个表:create table usr (name text ,pass text);
create table record(name text,date char ,word text );

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在线词典项目描述: 版本号:v1.1 升级描述:1. 同时支持管理员(用户名:root,密码:1)和普通用户 2. 管理员可以查询所有用户的使用记录 服务器: 1. 支持并发服务器,每有一个客户端connect成功后,提示某某客户端已连接并打印客户端的ip和端口号。 2. 服务器程序可在任意IP地址上运行,并且允许IP地址快速重用 3. 接收到客户端的信息后,可以执行相应的操作:注册,登陆,退出 注册:接收到注册新用户指令后,可以创建sqlite3数据库,将用户名和密码存储到数据库的user表中(用户名name为primary key)。 登陆:接收到登陆命令,可以查询客户端输入的用户名和密码数据库中有没有,有的话跳到下一个菜单(查询单词,历史纪录,退出),没有的话打印错误信息。 查询单词:用户输入单词,服务器从dict.txt文件中遍历有无该单词,有的话打印释义,没有的话打印错误信息,并将用(户名,时间,单词)存储到数据库的history_record表中。(‘#’返回上一级菜单) 历史纪录:用户选择历史记录查询,服务器从数据库的history_record表查询相同name的记录,每查询到一条,调用一次callback将信息发送到客户端,查询完毕后通知客户端。 退出:客户端退出,服务器打印"client exit!" 退出:客户端退出,服务器打印"client exit!" 客户端: 1. 客户端输入./client 192.168.23.128(服务器IP地址) 10000(端口号),参数格式不对或少报错,端口号不能小于5000,小于5000报错 2. 客户端支持注册,登陆,退出 注册:向服务器发送用户名和密码,接收服务器返回来的信息,注册成功/当前用户已存在 登陆:用户输入用户名和密码,客服端将用户名和密码发送给服务器,接收服务器返回的信息,如果OK,打印Login OK! 进入下一菜单(查询单词,历史纪录,退出),否则打印错误信息 查询单词:用户输入单词,客户端将单词发送给服务器,服务器将释义返回给客户端,客户端将释义打印出来 历史纪录:用户选择历史记录查询,客户端将信息发送给服务器,服务器循环把该用户的历史查询记录发送给客户端,客户端循环将其打印出来。 退出:客户端关闭套接字后结束进程 退出:客户端关闭套接字后结束进程
安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项目-在线词典源码(源码).zip安卓app开发项

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值