C项目-在线词典查询

词典查询演示

1、项目概述

项目需要:
1、语言:纯C语言
2、系统:linux系统,ubontu64位
3、数据库:slqite小型数据库(自己准备)
4、数据来源:1.txt(自备一个装了单词和意思的文档)

2、项目流程

1、将单词先导入数据库
2、网络配置
3、编写server服务器代码,client客户端代码

3、直接上源码

1、对数据库函数的封装

sqldata.h

#ifndef _SQLDATA_
#define _SQLDATA_
#include 
#include 
#include 
#include 
#include 
#define SQLNAME "my.db"
#define WORDPATH "1.txt"  // 数据来源
sqlite3 * Create_db_sql(char *pathname);	/*1、创建数据库函数*/
int Create_db_usr(sqlite3 *p);		/*2、创建usr表*/
int Create_db_words(sqlite3 *p);		/*3、创建words表*/
int Create_db_history(sqlite3 *p);		/*4、创建history表*/
int sql_init(char *pathname);			/*5、数据库初始化函数*/
int Delete_sql_table(char *sqlname,char *tablename);/*6、删除表函数*/
//7、对表内数据的查询
		/*5.1 select %s from usr where %s='%s';*/
		/*usr(id integer,name text, passwd varchar)*/
char *Select_usr_data(char *sqlname,char *name);
char *Select_words_data(char *sqlname,char *word);
int Select_history_data(char *sqlname,char *name,char **word,char **mean);
//8、增加表内数据
		/*insert into usr values(id,name,passwd);*/
		/*usr(id integer,name text, passwd varchar)*/
int Insert_usr_data(char *sqlname,int id,char *name,char *passwd);
int Insert_words_data(char *sqlname,char *word,char *mean);
int Insert_history_data(char *sqlname,char *name,char *word,char *mean);
//9、删除表内数据
		/*7.1 delete from %s where %s='%s';*/
		/*usr(id,name,passwd)------------->pstr=name*/
		/*history(id,word,mean)----------->pstr=word*/
		/*words(word,mean)---------------->pstr=word*/
int Delete_table_data(char *sqlname,char *tablename,char *pstr);
//10、单词插入数据库 
		/*sqlname:要插入的数据库名称,wordpath:数据来源;*/
int put_word_sql(char *sqlname,char *wordpath);

#endif

sqldata源码

sqlidata.c

#include "sqldata.h"

#define SQLMAX 128  //buf-sql MAXLEN

#if 1
//1、数据库的建立
sqlite3 * Create_db_sql(char *pathname)
{
	sqlite3 *db;
	if( sqlite3_open(pathname,&db) != SQLITE_OK)
	{
		printf("Create_db_sql:%s\n",sqlite3_errmsg(db));
		return NULL;
	}
	return db;
}
//2、数据库表的建立
		/*2.1 create table if not exists usr(int integer,name text,passwd varchar);*/
int Create_db_usr(sqlite3 *p)
{
	if(p == NULL)
	{
		printf("Create_db_usr *p = NULL\n");
		return -1;
	}
	/*sqlite3 *db*/
	sqlite3 *db = p;
	//1.open db
	char sql[SQLMAX] = {0};
	sprintf(sql,"create table if not exists usr(id integer,name text,passwd varchar);");
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Create_db_usr:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	return 0;
}
		/*2.2 create table if not exists words(word text,mean nvarchar);*/
int Create_db_words(sqlite3 *p)
{
	if(p == NULL)
	{
		printf("Create_db_words *p = NULL\n");
		return -1;
	}
	/*sqlite3 *db*/
	sqlite3 *db = p;
	//1.open db
	char sql[SQLMAX] = {0};
	sprintf(sql,"create table if not exists words(word text,mean nvarchar);");
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Create_db_words:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	return 0;
}
		/*2.3 create table if not exists history(id integer,word text,mean nvarchar);*/
int Create_db_history(sqlite3 *p)
{
	if(p == NULL)
	{
		printf("Create_db_history *p = NULL\n");
		return -1;
	}
	/*sqlite3 *db*/
	sqlite3 *db = p;
	//1.open db
	char sql[SQLMAX] = {0};
	sprintf(sql,"create table if not exists history(name text,word text,mean nvarchar);");
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Create_db_history:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	return 0;
}
#endif
//3、数据库初始化
int sql_init(char *sqlname)
{
	if(sqlname == NULL)
	{
		printf("sqlname is NULL\n");
		return -1;
	}
	sqlite3 *db = Create_db_sql(sqlname);
	if(db==NULL)
	{
		return -1;
	}
	printf("Create_db_sql success!\n");
	if( Create_db_usr(db) < 0)
	{
		return -1;
	}
	printf("Create_db_usr success!\n");
	if( Create_db_words(db) < 0)
	{
		return -1;
	}
	printf("Create_db_words success!\n");
	if( Create_db_history(db) < 0)
	{
		return -1;
	}
	printf("Create_db_history success!\n");
	
	if(put_word_sql(SQLNAME,WORDPATH) == 0)
	{
		printf("%s 单词插入数据库成功\n",WORDPATH);
	}
	else
	{
		printf("input words to sql fail!\n");
		return -1;
	}
	sqlite3_close(db);
	return 0;
}
//4、数据库表的删除
		/*4.1 drop table "tablename";*/
int Delete_sql_table(char *sqlname,char *tablename)
{
	if(sqlname == NULL || tablename == NULL)
	{
		printf("sqlname or tablename is NULL\n");
		return -1;
	}
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Delete_sql_table_open:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	sprintf(sql,"drop table %s;",tablename);
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Delete_sql_table_drop table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	sqlite3_close(db);	//用完数据库关闭数据库	
	return 0;
}
//5、对表内数据的查询
		/*5.1 select %s from usr where %s='%s';*/
		/*usr(id integer,name text, passwd varchar)*/
		/* 问题:返回值怎么设计  */
char * Select_usr_data(char *sqlname,char *name)
{
	if(sqlname == NULL || name == NULL)
	{
		printf("Select_usr_data:str is NULL\n");
		return NULL; 
	}
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	/*back value*/
	char *r = "";
	/*seek */
	char **result;
	int nRow = 0,nColumn = 0;
	char *p = name;
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Select_usr_data:%s\n",sqlite3_errmsg(db));
		return NULL;
	}
	
	sprintf(sql,"select passwd from usr where name='%s';",p);
	
	if( sqlite3_get_table(db,sql,&result,&nRow,&nColumn,NULL) != SQLITE_OK)
	{
		printf("Select_usr_data table:%s\n",sqlite3_errmsg(db));
		return NULL;
	}
	else
	{
		if(nRow >= 1)
		{
			printf("%s\n",result[nColumn]);
			r=result[nColumn];
		}
	}
	sqlite3_close(db);
	return r;	
}
		/*5.2 select * from history where id=%d;*/
int Select_history_data(char *sqlname,char *name,char **word,char **mean)
{
	if(sqlname == NULL)
	{
		printf("Select_history_data:str is NULL\n");
		return -1;
	}
	static int count = 1;
	char *p = name;
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	/*seek */
	char **result;
	int nRow = 0,nColumn = 0;
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Select_history_data:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	
	sprintf(sql,"select * from history where name='%s';",p);
	
	if( sqlite3_get_table(db,sql,&result,&nRow,&nColumn,NULL) != SQLITE_OK)
	{
		printf("Select_history_data table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	else
	{
		if(nRow >= 1 && count <= nRow)
		{
			nColumn = count * nColumn;
			*word=result[nColumn+1];
			*mean=result[nColumn+2];
			count++;
		}else if(count > nRow)
		{
			count = 1;
			return 1;
		}
	}
	sqlite3_close(db);
	return 0;
}
		/*5.3 select mean from words where word='%s';*/
char *Select_words_data(char *sqlname,char *word)
{
	if(sqlname == NULL || word == NULL)
	{
		printf("Select_words_data:str is NULL\n");
		return NULL;
	}
	/*back value*/
	char *r = "";
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	/*seek */
	char **result;
	int nRow = 0,nColumn = 0;
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Select_words_data:%s\n",sqlite3_errmsg(db));
		return NULL;
	}
	
	sprintf(sql,"select mean from words where word='%s';",word);
	
	if( sqlite3_get_table(db,sql,&result,&nRow,&nColumn,NULL) != SQLITE_OK)
	{
		printf("Select_words_data table:%s\n",sqlite3_errmsg(db));
		return NULL;
	}
	else
	{
		if(nRow >= 1)
		{
			//printf("%s\n",result[nColumn]);
			r=result[nColumn];
		}
	}
	sqlite3_close(db);
	return r;
}
//6、增加表内数据
		/*6.1 insert into usr values(id,name,passwd);*/
		/*usr(id,name,passwd)*/
		/*words(word,mean)*/
		/*history(id,word,mean)*/
int Insert_usr_data(char *sqlname,int id,char *name,char *passwd)
{
	if(sqlname == NULL || name == NULL || passwd == NULL)
	{
		printf("Insert_usr_data:str is NULL\n");
		return -1;
	}
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Insert_usr_data:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	
	sprintf(sql,"insert into usr values(%d,'%s','%s');",id,name,passwd);
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Insert_usr_data table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	sqlite3_close(db);
	return 0;	
}
		/*6.2 insert into words values(word,mean);*/
int Insert_words_data(char *sqlname,char *word,char *mean)
{
	if(sqlname == NULL || word == NULL || mean == NULL)
	{
		printf("Insert_words_data:str is NULL\n");
		return -1;
	}
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Insert_usr_data:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	
	sprintf(sql,"insert into words values('%s','%s');",word,mean);
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Insert_words_data table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	sqlite3_close(db);
	return 0;	
}
		/*6.3 insert into history values(id,word,mean);*/
int Insert_history_data(char *sqlname,char *name,char *word,char *mean)
{
	if(sqlname == NULL || word == NULL || mean == NULL)
	{
		printf("Insert_history_data:str is NULL\n");
		return -1;
	}
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	char *p = word;
	char *q = mean;
	char *s = name;
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Insert_history_data:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	
	sprintf(sql,"insert into history values('%s','%s','%s');",s,p,q);
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Insert_history_data table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	sqlite3_close(db);
	return 0;	
}
//7、删除表内数据
		/*7.1 delete from %s where %s='%s';*/
		/*usr(id,name,passwd)------------->pstr=name*/
		/*history(id,word,mean)----------->pstr=word*/
		/*words(word,mean)---------------->pstr=name*/
int Delete_table_data(char *sqlname,char *tablename,char *pstr)
{
	if(sqlname == NULL || tablename == NULL || pstr == NULL)
	{
		printf("Delete_table_data:str is NULL\n");
		return -1;
	}
	/*commnd*/
	char *q = (char *)malloc(20);
	/*sqlite_commnd*/
	char sql[SQLMAX] = {0};
	if(strcmp(tablename,"usr") == 0){strcpy(q,"name");}
	else if(strcmp(tablename,"words") == 0){strcpy(q,"word");}
	else if(strcmp(tablename,"history") == 0){strcpy(q,"word");}
	else 
	{
		printf("没有这个表\n");
		return -1;
	}
	sqlite3 *db;
	if( sqlite3_open(sqlname,&db) != SQLITE_OK)
	{
		printf("Delete_table_data:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	
	sprintf(sql,"delete from %s where %s='%s';",tablename,q,pstr);
	
	if( sqlite3_exec(db,sql,NULL,NULL,NULL) != SQLITE_OK )
	{
		printf("Delete_table_data table:%s\n",sqlite3_errmsg(db));
		return -1;
	}
	free(q);
	sqlite3_close(db);
	return 0;
}
//8、单词全部插入数据库
		/*sqlname:要插入的数据库名称,wordpath:数据来源;*/
int put_word_sql(char *sqlname,char *wordpath)
{
	if(sqlname == NULL || wordpath == NULL)
	{
		printf("put_word_sql:str is NULL\n");
		return -1;
	}
	/*sqlite3*/
	sqlite3 *db;
	/*put words value*/
	char readbuf[1024] = {0};
	char *word = "";
	char *mean = "";
	int count = 0;
    	if( sqlite3_open(sqlname,&db) != SQLITE_OK )
    	{
        	printf("error:%s\n",sqlite3_errmsg(db));
        	return -1;
    	}
	FILE *fp = fopen(wordpath,"r");
	if(fp == NULL)
	{
		perror("fopen");
		return -1;
	}
	printf("open %s success ready to put words into sql\n",wordpath);
	while(fgets(readbuf,sizeof(readbuf),fp) != NULL)
    	{
        	if(readbuf[strlen(readbuf)-1] == '\n')
        	{
            		count++;
            		word = strtok(readbuf," ");
            		mean = strtok(NULL,"\n");
            		if(Insert_words_data(SQLNAME,word,mean) < 0)
            		{
            			printf("插入失败,重新插入!\n");
            			continue;
            		}
            		//printf("%d:%s\t%s\n",count,word,mean);
        	}
    	}
	return 0;
}


server.h

server.h

#ifndef _SERVER_H_
#define _SERVER_H
#include 
//socket
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include 

#define MAXMEM 5 //listen maxmember queue

int server_init(int port,char *ip);
int WaitForClient(int sockfd);

#endif

server.c

#include "server.h"

// 绑定IP和端口号放到网络上,一定要确定绑定操作的正确。主机字节序转换成网络字节序;
int server_init(int port,char *ip)
{
	int reuseaddr = 1;
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
    //得到套截字
    if(sockfd < 0)
    {
        perror("sockfd");
        return -1;
    }
    //设置端口号重用
    if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr) ) < 0)
    {
    	perror("socket");
    	return -1;
    }
    struct sockaddr_in s_addr;//save host IP and PORT,put it online
	int s_len = sizeof(s_addr);
    //准备一个saddr给bind函数
    bzero(&s_addr,0);
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(port);
    s_addr.sin_addr.s_addr=inet_addr(ip);	
    	
    if( bind(sockfd,(struct sockaddr *)&s_addr,s_len ) <0)
    {
        perror("bind");
        return -1;
    }
    //设置同一时刻最大的连接数
    if( listen(sockfd,MAXMEM) < 0)
    {
        perror("listen");
        return -1;
    }
	return sockfd;
}
//等待客户端连接函数

int WaitForClient(int sockfd)
{	
 	int connfd;
	struct sockaddr_in c_addr;//save connect client IP and PORT 
 	socklen_t c_len = sizeof(c_addr);
    	bzero(&c_addr,0);        
   	//accept等待客户端连接
       if((connfd = accept(sockfd,(struct sockaddr *)&c_addr,&c_len)) < 0)
       {
           perror("accept");
           return -1;
       }
       printf("connect from [%s:%d]\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
       
      return connfd;
}



thread.h

#ifndef _THREAD_H_
#define _THREAD_H_
#include 
#include 
#include 
#include 
#include 
#define MSGLEN 128
#define SECOND 1	//  清屏幕的快慢1~65535
void *Data_client_server(void *arg);
char *Recv_client(int connfd);
int Send_client(int connfd,char *pmsg);

int denglu(int connfd);
int zhuce(int connfd);

int find_history(int connfd,char *name);
int find_word(int connfd,char *name);

void Clear(int second,char *tips);
#endif

thread.c

#include "thread.h"
#include "sqldata.h"

void *Data_client_server(void *arg)
{
	int connfd = *(int *)arg;
	/*msg */
	char  msg[MSGLEN] = {0};
	while(1)
	{
		Clear(SECOND,"等待客户端登陆选择");
		memset(msg,0,MSGLEN);
		strcpy(msg,Recv_client(connfd));
		switch(msg[0])
		{
			case 'D':denglu(connfd);break;
			case 'Z':zhuce(connfd);break;
			case 'T':Clear(SECOND,"当前客户端离开");goto AA;
			default:printf("re-enter\n");break;
		}
		
	}
AA:
	close(connfd);
	pthread_exit(NULL);
}
//1、接收客户端消息
char *Recv_client(int connfd)
{
	int ret = 0;
	/*back value*/
	char *r = "";
	/*msg*/
	char msg[MSGLEN] = {0};
	ret = read(connfd,msg,sizeof(msg));
	if(ret < 0)
	{
		perror("Recv_client");
		return NULL;
	}else if(ret == 0)
	{
		printf("client laved!\n");
		return NULL;
	}
	r = msg;
	return r;
}
//2、给客户端发送消息
int Send_client(int connfd,char *pmsg)
{
	/*msg*/
	char *msg = pmsg;
	if(write(connfd,msg,strlen(msg))<0)
	{
		printf("wrtie to client fail\n");
		return -1;
	}
	return 0;	
}
//3、登陆账号功能
int denglu(int connfd)
{
Clear(SECOND,"登陆");
	/*msg*/
	char *msg = "";
	/*name passwd*/
	char name[20] = {0};
	char passwd[20] = {0};
	//1、对比账号
	while(1)
	{
		//调用查询函数
		strcpy(name,Recv_client(connfd));
		printf("name:%s\n",name);
		strcpy(passwd,Recv_client(connfd));
		printf("passwd:%s\n",passwd);
		if( strcmp(passwd,Select_usr_data(SQLNAME,name) ) == 0)
		{
			//2、登陆成功---选择功能
			Send_client(connfd,"1");
			Clear(SECOND,"登陆成功");
			while(1)
			{
				Clear(SECOND,"功能选择");
				msg = Recv_client(connfd);
				switch(msg[0])
				{
					//2-1---单词查询
					case '1':find_word(connfd,name);break;
					//2-2---历史记录
					case '2':find_history(connfd,name);break;
					//2-3---返回上一级目录
					case '0':Clear(SECOND,"返回登陆");goto AA;
					default:break;
				}
			}
		}
		else
		{
			//3、登陆失败---处理
			Send_client(connfd,"0");
			Clear(SECOND,"登陆失败");
				//3-1---返回登陆功能选择
			break;
		}
	}
AA:
	return 0;
}
//4、单词查询
int find_word(int connfd,char *name)
{
	Clear(SECOND,"查询单词");
	char *p = name;
	/*word mean*/
	char word[20] = {0};
	char mean[MSGLEN] = {0};
	while(1)
	{
AA:
		strcpy(word,Recv_client(connfd));
		if(strcmp(word,"QUIT") == 0)
		{
			Clear(SECOND,"客户端退出单词查询");
				break;
		}
		//查询word并且返回mean
		printf("word:%s\n",word);
		 strcpy(mean,Select_words_data(SQLNAME,word));//组装历史查询记录Insert_history_data(char *sqlname,char *name,char *word,char *mean);
		 printf("mean:%s\n",mean);
		if( mean[0] == '\0')
		{
			Clear(1,"没有这个单词");
			Send_client(connfd,"NO");
			goto AA;
		}
		Send_client(connfd,mean);
		if(Insert_history_data(SQLNAME,p,word,mean) < 0)
		{
			printf("历史记录插入失败\n");
		}
		
	}
	return 0;
}
//5、历史记录查询
int find_history(int connfd,char *name)
{
	Clear(SECOND,"历史记录查询");
	char *p = name;
	/*word mean*/
	char *word = "";
	char *mean = "";
	int ret = 0;
	char history[MSGLEN] = {0};
	while(1)
	{
		ret = Select_history_data(SQLNAME,p,&word,&mean);
		//查询word并且返回mean
		if( ret == 0)
		{
			printf("history:%c %c\n",word[0],mean[0]);
			sprintf(history,"%s %s",word,mean);
			if(history[0] == '\0' || word[0] == '\0' || mean[0] == '\0')
			{
				Clear(SECOND,"没有记录或者查询完毕");
				Send_client(connfd,"END");
				break;
			}
			Send_client(connfd,history);
			memset(history,0,sizeof(history));
		}
		else if(ret == 1)
		{
			Clear(SECOND,"查询完毕");
			Send_client(connfd,"END");
			break;
		}
		else if(ret < 0)
		{
			Clear(SECOND,"查询错误");
			Send_client(connfd,"ERR");
			break;
		}
	}
	return 0;
}
//6、注册账号功能
int zhuce(int connfd)
{
	Clear(SECOND,"注册");
	/*name passwd*/
	char name[20] = {0};
	char passwd[20] = {0};
	/*注册失败次数*/
	while(1)
	{
		strcpy(name,Recv_client(connfd));
		//在usr表中插入用户,插入成功返回1,插入失败返回0;
		strcpy(passwd,Recv_client(connfd));
		//要先判断一下,用户表里面有没有用户
		if(strcmp(passwd,Select_usr_data(SQLNAME,name)) != 0)
		{
			if( Insert_usr_data(SQLNAME,connfd,name,passwd) < 0)
			{
				Send_client(connfd,"0");
				break;
			}
			else
			{
				Send_client(connfd,"1");
				break;
			}
		}
		else
		{
			Send_client(connfd,"2");
			break;
		}
	}
	return 0;
}


void Clear(int second,char *tips)
{
	char *p = tips;
	printf("		%s\n",p);
	sleep(second);
	system("clear");
}

main.c测试函数,服务器代码到这里结束。

注意一下,数据库初始化函数开一次就可以关了,重新编译再用。不然重复用数据库会追加数据,重复写数据进去

#include "sqldata.h"
#include "server.h"
#include "thread.h"


int main(int argc,char *argv[])
{
#if 1
	if(sql_init("my.db") < 0)
	{
		printf("sql_init fail!\n");
		return -1;
	}
	Clear(SECOND,"单词数据库初始化成功");
#endif

	int sockfd = server_init(8888,"192.168.12.189");
	if( sockfd < 0)
	{
		printf("server_init fail!\n");
        return -1;
	}
	Clear(SECOND,"服务器网络初始化成功") ;
	int connfd[MAXMEM];
	pthread_t tid[MAXMEM];
	int i = 0;
	for(i = 0; i < MAXMEM; i++)
	{
		connfd[i] = -1;
	}
	while(1)
	{
		for(i = 0; i < MAXMEM; i++)
		{
			if(connfd[i] == -1)
				break; 
		}
		
		connfd[i] = WaitForClient(sockfd);
		if(connfd[i] < 0)
		{
			printf("accept:\n");
		}
		pthread_create(&tid[i],NULL,Data_client_server,(void *)&connfd[i]);
	}
	close(sockfd);
	return 0;
}

4、客户端代码

login.c

#include "login.h"

void Zmenu()
{
	puts("|------------------------------|");
    	puts("|---------1.登陆---------------|");
    	puts("|---------2.注册---------------|");
    	puts("|---------0.退出---------------|");
    	puts("|------------------------------|");
}

void CGmenu()
{
	puts("|----------------------------------|");
    	puts("|---------1.查询单词---------------|");
    	puts("|---------2.查询历史---------------|");
    	puts("|---------0.退出-------------------|");
    	puts("|----------------------------------|");
}
int Send_server(int sockfd,char *pmsg)
{
	char *msg = pmsg;
	if(write(sockfd,msg,strlen(msg)) < 0)
	{
		perror("Send_server");
		return -1;
	}
	return 0;
}
char *Recv_server(int sockfd)
{
	int ret = 0;
	/*back value*/
	char *r = "";
	/*msg*/
	char msg[MSGLEN] = {0};
	ret = read(sockfd,msg,sizeof(msg));
	if(ret < 0)
	{
		perror("Recv_client");
		return NULL;
	}
	r = msg;
	return r;
}
int denglu(int sockfd)
{
	Clear(SECOND,"登陆");
	/*buf send to server*/
	char msg[MSGLEN] = {0};
	char *pstr = "";
	/*name passwd*/
	char name[20] = {0};
	char passwd[20] = {0};
	//1、告诉服务器,客户端要登陆,给它发送“D”
	Send_server(sockfd,"D");
	//2、客户端组装好用户名和密码发送给服务器进行比对;
	while(1)
	{
		printf("input name------>");
		scanf("%s",name);
		//fgets(name,sizeof(name),stdin);
		Send_server(sockfd,name);
		printf("input passwd---->");
		scanf("%s",passwd);
		//fgets(passwd,sizeof(passwd),stdin);
		Send_server(sockfd,passwd);
		printf("等待密码验证......\n");
		pstr = Recv_server(sockfd);
			//2-1---登陆成功收到1
			if(pstr[0] == '1')
			{
				Clear(SECOND,"登陆成功");
				//进行功能选择
				while(1)
				{
					CGmenu();
					printf("input:");
					scanf("%s",msg);
					Send_server(sockfd,msg);
					switch(msg[0])
					{
						case '1':find_word(sockfd);break;
						case '2':find_history(sockfd);break;
						case '0':Clear(SECOND,"返回登陆功能选择");goto AA;//Clear(SECOND,"返回登陆功能选择")
						default:break;
					}
				}
			}
			//2-2---登陆失败收到0
			if(pstr[0] == '0')
			{
				printf("登陆失败\n");
				Clear(SECOND,"登陆失败");
				break;
			}
	}
AA:
	return 0;
}

//单词查询
int find_word(int sockfd)
{
	Clear(SECOND,"单词查询");
	/*word mean*/
	char word[20] = {0};
	char mean[MSGLEN] = {0};
	while(1)
	{
AA:
		printf("input words-->");
		scanf("%s",word);
		//fgets(word,sizeof(word),stdin);
		if(strcmp(word,"QUIT") == 0)
		{
			Send_server(sockfd,word);
			Clear(SECOND,"返回功能选择");
			break;
		}
		Send_server(sockfd,word);
		strcpy(mean,Recv_server(sockfd));
		if(strncmp(mean,"NO",2) == 0)
		{
			Clear(1,"没有这个单词");
			goto AA;
		}
		printf("%s\t%s\n",word,mean);
		memset(word,0,20);
		memset(mean,0,128);
	}
	return 0;
}
//历史记录查询
int find_history(int sockfd)
{
	Clear(SECOND,"历史记录查询");
	/*history buf*/
	char history[MSGLEN] = {0};
	while(1)
	{
		strcpy(history,Recv_server(sockfd));
		if(strncmp(history,"END",3) == 0)
		{
			Clear(SECOND,"查询完毕");
			break;
		}
		if(strncmp(history,"ERR",3) == 0)
		{
			Clear(SECOND,"查询单词错误");
			break;
		}
		printf("history:%s\n",history);
		memset(history,0,128);
	}
	return 0;
}
int zhuce(int sockfd)
{
	Clear(SECOND,"注册");
	char *pstr = "";
	/*name passwd*/
	char name[20] = {0};
	char passwd[20] = {0};
	//1、告诉服务器,客户端注册,给它发送“Z”
	Send_server(sockfd,"Z");
	//2、客户端组装好用户名和密码发送给服务器进行比对;
	while(1)
	{
		printf("input name------>");
		scanf("%s",name);
		Send_server(sockfd,name);
		printf("input passwd---->");
		scanf("%s",passwd);
		Send_server(sockfd,passwd);
		printf("等待注册......\n");
		pstr = Recv_server(sockfd);
			//2-1---登陆成功收到1
			if(pstr[0] == '1')
			{
				Clear(SECOND,"注册成功");//要告诉服务器注册成功
				break;
			}
			//2-2---登陆失败收到0
			if(pstr[0] == '0')
			{
				Clear(SECOND,"注册失败");//要告诉服务器注册失败
				break;
				
			}
			if(pstr[0] == '2')
			{
				Clear(SECOND,"用户已经存在");
				break;
			}
	}
	return 0;
}

void Clear(int second,char *tips)
{
	char *p = tips;
	printf("		%s\n",p);
	sleep(second);
	system("clear");
}

void tuichu(int sockfd)
{
	Send_server(sockfd,"T");
	Clear(SECOND,"退出客户端");
}

login.h

#ifndef _LOGIN_
#define _LOGIN_
#include 
#include
#include
#include
#include
#include
#include
#include
#include

#define MSGLEN 128
#define SECOND 1	// 清屏秒数
/*Send_server(sockfd,msg);*/
int Send_server(int sockfd,char *pmsg);//将消息发送给服务器
/*Recv_server(sockfd);*/
char *Recv_server(int sockfd);	//接收来自服务器的消息
void Zmenu();				//登陆注册菜单
void CGmenu();				//功能菜单

int denglu(int sockfd);

int zhuce(int sockfd);

int find_word(int sockfd);
int find_history(int sockfd);
void tuichu(int sockfd);
void Clear(int second,char *tips);		//清屏函数

#endif

main.c客户端调试

#include "login.h"

int main(int argc,char* argv[])
{
	if(argc < 3)
	{
		printf("./c  \n");
		return -1;
	}
	/*commnd*/
	char commnd[MSGLEN] = {0};
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd==-1)
    	{
        	perror("server_init error!");
        	return -1;
    	}
    	struct sockaddr_in saddr;
    	memset(&saddr,0,sizeof(saddr));
    	saddr.sin_family=AF_INET;
    	saddr.sin_port=htons(atoi(argv[1]));
    	saddr.sin_addr.s_addr=inet_addr(argv[2]);
    	if(connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr))==-1)
    	{
      		perror("connect fail!");
      		return -1;
    	}
	printf("client sockfd_init success!\n");
	sleep(1);
	system("clear");
	
	while(1)
	{
		//1、主菜单 
		Zmenu();
		printf("input:");
		//scanf("%s",commnd);
		fgets(commnd,MSGLEN,stdin);
		//2、功能选择
		switch(commnd[0])
		{
			//2-1---登陆
			case '1':denglu(sockfd);break;
			//2-2---注册
			case '2':zhuce(sockfd);break;
			//2-3---退出,返回Zmenu();
			case '0':tuichu(sockfd);goto BB;
			default:printf("\n");system("clear");break;//system("clear")
		}
		
	}
BB:
	close(sockfd);
	return 0;
}

5、结构和makefile

project:
		server:
				makefile;
				1.txt;
				app;------->可执行文件
				my.db;
				src:
					thread.c
					seldata.c
					server.c
					main.c
				include:
						server.h
						thread.h
						sqldata.h
		client:
				makefile;
				c;---------->可执行文件
				src:
					login.c
					main.c
				include:
						login.h

客户端makefile

CC=gcc
CFLAGS=-c -g -Wall -I ./include
SRCS =$(wildcard ./src/*.c)
OBJS =$(patsubst %.c,%.o,$(SRCS))
app:$(OBJS)
	$(CC) $(OBJS) -o c
clean:
	rm client -rf
cleano:
	rm ./src/*.o -rf

服务器makefile

CC=gcc
CFLAGS=-c -Wall -g -I ./include
SRCS = $(wildcard ./src/*.c)
OBJS =$(patsubst %.c,%.o,$(SRCS))

app:$(OBJS)
	$(CC) $(OBJS) -o app -lpthread -lsqlite3
cleano:
	rm ./src/*.o -rf
cleana:
	rm app -rf
cleandb:
	rm my.db -rf


6、在线词典查询演示

你可能感兴趣的:(练手,的项目,数据库,sql,服务器)