电子词典项目

目录

目录

头文件:dict.h:

源文件:dict.c:

服务器测试文件:serDict.c:

客户端测试文件:cliDict.c:


头文件:dict.h:
#ifndef __DICT_H__
#define __DICT_H__
#include<myhead.h>
#include<sqlite3.h>

#define SERIP "192.168.114.73"
#define PORT 8888

#define ERR_MSG(msg) do{\
	printf("%d: ",__LINE__);\
	perror(msg);\
}while(0);

/*服务器使用  */
//词典数据库的初始化和导入
int dict_init(sqlite3 *db);

//TCP服务器搭建函数
int TCP_ser_set(struct sockaddr_in* psin);

//回收子进程函数
void handler(int signum);

//子进程中的操作
void child_operate(int newfd, sqlite3 *db);
/*服务器使用  */

/*客户端使用  */
//TCP客户端搭建函数
int TCP_cli_set();

//客户端中的操作
void cli_operate(int cfd);

/*客户端使用  */
#endif
源文件:dict.c:
#include<myhead.h>
#include<sqlite3.h>
#include "dict.h"

int do_create(sqlite3 *db);
int do_insert(sqlite3 *db, char * English, char *Chinese);
int msg_get(FILE *fp, char*pEng, char *pChin);
int do_init(sqlite3 *db);
int usrname_not_reuse(sqlite3 *db, const char *usrname, const char *tablename);

int dict_init(sqlite3 *db)
{
	
	//初始化数据库中词典数据表
	do_init(db);
	printf("数据库初始化成功\n");

	//打开文件
	FILE *fp;
	char English[32] = "";
	char Chinese[64] = "";
	if(NULL == (fp=fopen("./dict.txt","r"))){
		printf("%d:",__LINE__);
		perror("fopen error");
		return -1;
	}

	//创建表格
	do_create(db);

	printf("词典数据导入中\n...\n");
	while(1){
		//从dict.txt中读取一行的数据
		bzero(English, sizeof(English));
		bzero(Chinese, sizeof(Chinese));
		msg_get(fp, English, Chinese);
		//将English和Chinese写入表格中
		do_insert(db, English, Chinese);

		//printf("%s\t%s\n",English, Chinese);

		if(feof(fp)){
			printf("导入成功\n");
			break;
		}
	}

	
	//关闭文件
	fclose(fp);
	return 0;
}

int msg_get(FILE *fp, char* pEng, char *pChin){
	char tmp = 0;
	int i = 0;
	while((tmp = fgetc(fp))!=' '){
		pEng[i] = tmp;
		i++;
		if(feof(fp)){
			return 0;
		}
	}
	i = 0;
	while(fgetc(fp)==' ');
	fseek(fp,-1,SEEK_CUR);
	while((tmp = fgetc(fp))!='\n'){
		pChin[i] = tmp;
		i++;
		if(feof(fp)){
			pChin[i-1] = 0;
			break;
		}
	}
	return 0;
}

int do_create(sqlite3 *db){
	if(db == NULL){
		printf("数据库不存在\n");
		return -1;
	}

	//创建词典数据表
	char sql[128] = "create table if not exists dict(ENGLISH char, TRANSLATION char);";

	char *errmsg = NULL;
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
		printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}

	//创建已注册用户数据表
	bzero(sql,sizeof(sql));
	strcpy(sql,"create table if not exists registeredUsr(id char primary key, passwd char);");

	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
		printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}
	//创建已登录用户数据表
	bzero(sql,sizeof(sql));
	strcpy(sql,"create table if not exists loadedUsr(id char primary key, passwd char);");

	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
		printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}


	//创建成功
	return 0;
}

int do_init(sqlite3 *db){
	if(db == NULL){
		printf("数据库不存在\n");
		return -1;
	}

	char sql[128] = "drop table dict;";

	char *errmsg = NULL;
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
		printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}

	//创建成功
	return 0;
}

//插入表格函数
int do_insert(sqlite3 *db, char * English, char *Chinese){
	if(db == NULL){
		printf("数据库不存在\n");
		return -1;
	}

	char sql[128] = "";
	snprintf(sql, sizeof(sql),"insert into dict values(\"%s\", \"%s\");",English, Chinese);

	char *errmsg = NULL;
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
		printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}

	return 0;
}

//TCP服务器搭建函数
int TCP_ser_set(struct sockaddr_in* psin){
	int sfd;
	if((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		ERR_MSG("socket error");
		return -1;
	}

	int optval = 1;
	//允许端口快速复用
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))<0){
		ERR_MSG("setsockopt error");
		return -1;
	}

	//获取地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(SERIP);
	* psin = sin;
	//绑定
	if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))<0){
		ERR_MSG("bind error");
		return -1;
	}

	//设为监听
	if(listen(sfd,128)<0){
		ERR_MSG("listen error");
		return -1;
	}

	printf("服务器搭建成功\n");
	return sfd;
}

//回收子进程函数
void handler(int signum){
	while(waitpid(-1,NULL,WNOHANG)!=0);
}

//子进程中的操作
void child_operate(int newfd, sqlite3 *db){
	//判断传入的newfd是否合法
	if(newfd<0){
		printf("连接失败\n");
		return;
	}
	char buf[150] = " ";
	//用于读取数据包中的操作码
	unsigned short *operatorPtr = (unsigned short*)buf;
	//用于登录后记录用户名,便于读写对应用户的历史记录数据库
	char usrname[20] = " ";
	//用于读取数据包中的用户名
	char *usrnamePtr = buf + 2;
	//需要后续计算得到数据包中数据的位置
	char *dataPtr = NULL;
	//获取用户名的长度
	int usrnameLen = 0;
	//定义一个变量接收返回值
	int res = 0;
	//保存命令的数组
	char sql[128] = " ";
	while(1){
		bzero(buf,sizeof(buf));
		//接收
		if(recv(newfd, buf, sizeof(buf), 0) == -1){
			ERR_MSG("recv error");
			break;
		}
		//获取的是用户名的长度
		usrnameLen = strlen(usrnamePtr);
		//可知数据包中数据的位置为
		dataPtr = usrnamePtr + usrnameLen + 1;
		//printf("%s\n",buf);
		//send(newfd,buf,sizeof(buf),0);
		//注册
		if(1 == *operatorPtr){
			//现在,usrnamePtr指向用户名,dataPtr是数据的起头,在注册里面,数据包应该保存用户对应的密码
			//检索已注册用户数据表,看看用户名是否存在
			res = usrname_not_reuse(db, usrnamePtr, "registeredUsr");

			if(-1 == res){
				//说明这个函数调用遇到问题
				//组一个返回包
				*operatorPtr = 7;
				strcpy(dataPtr,"there is something wrong");
			}else if(0 == res){
				//说明用户名已存在
				*operatorPtr = 7;
				strcpy(dataPtr,"用户名已存在");
			}else if(1 == res){
				//说明用户名不在数据库中,可以进行注册
				bzero(sql, sizeof(sql));

				snprintf(sql, sizeof(sql),"insert into registeredUsr values(\"%s\", \"%s\");",usrnamePtr, dataPtr);

				char *errmsg = NULL;
				if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
					printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
					break;	
				}

				*operatorPtr = 7;
				strcpy(dataPtr,"注册成功");

			}

		}else if(2 == *operatorPtr){
			//登录
			//现在,usrnamePtr指向用户名,dataPtr是数据的起头,在登录里面,数据包应该保存用户对应的密码
			//检索已登录用户数据表,看看用户名是否存在
			res = usrname_not_reuse(db, usrnamePtr, "registeredUsr");
			if(-1 == res){
				//说明这个函数调用遇到问题
				//组一个返回包
				*operatorPtr = 7;
				strcpy(dataPtr,"there is something wrong");
			}else if(1 == res){
				//说明在已注册表中未找到该用户,说明该账号还没被注册
				*operatorPtr = 7;
				strcpy(dataPtr,"该账号还未被注册,请先注册");
			}else if(0 == res){
				//说明在已注册表中找到了该用户,进行下一步登录操作
				res = usrname_not_reuse(db, usrnamePtr, "loadedUsr");
				if(-1 == res){
					//说明这个函数调用遇到问题
					//组一个返回包
					*operatorPtr = 7;
					strcpy(dataPtr,"there is something wrong");
				}else if(0 == res){
					//说明用户名已存在已登录数据表,说明用户已经登录
					*operatorPtr = 7;
					strcpy(dataPtr,"该账号已登录,请检查账号是否被盗用");
				}else if(1 == res){
					//说明该用户已注册且未登录,可以进行登录
					bzero(sql, sizeof(sql));

					char **result = NULL;
					int row = 0;
					int col = 0;
					char *errmsg = NULL;
					int flag = 0;

					snprintf(sql,sizeof(sql),"select id,passwd from registeredUsr;");

					if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
						printf("%d:sqlite3_get_table error\n",__LINE__);
						printf("%s\n",strerror(res));
						break;
					}

					//遍历比较,第0行是项的名,所以从第一行开始
					for(int i=col; i<=row*col; i+=col){
						if(strcmp(*(result+i),usrnamePtr) == 0&&strcmp(*(result+i+1),dataPtr) == 0){
							//登录成功后要将用户数据写入已登录用户数据表
							bzero(sql, sizeof(sql));

							snprintf(sql, sizeof(sql),"insert into loadedUsr values(\"%s\", \"%s\");",usrnamePtr, dataPtr);

							char *errmsg = NULL;
							if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
								printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
								break;	
							}
							//满足条件说明用户密码匹配成功,即登录成功
							*operatorPtr = 7;
							strcpy(dataPtr,"登录成功");
							//将登录成功的用户名保存
							strcpy(usrname,usrnamePtr);
							flag = 0;

							//然后应该新建一个对应用户的历史记录数据表
							bzero(sql, sizeof(sql));
							snprintf(sql, sizeof(sql),"create table if not exists %shis(ENGLISH char , TRANSLATION char, current timestamp default current_timestamp);",usrname);
							if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
								printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
								break;		
							}

							break;
						}else{
							flag = 1;
						}
					}

					if(1 == flag){
						*operatorPtr = 7;
						strcpy(dataPtr,"密码错误");
					}

				}
			}

		}else if(3 == *operatorPtr){
			//退出
			//先判断该进程中usrname字符串内是否有内容,如果有的话,说明用户是异常退出,先帮用户
			//退出登录,再进行退出操作
			if(usrname[0]!=0){
				//usrname字符串的第一个元素不为0,说明非空,检查usrname字符串内容是否在
				//已登录用户信息数据表中
				res = usrname_not_reuse(db, usrname, "loadedUsr");
				if(0 == res){
					//说明用户还在已登录用户信息表中,说明用户确实是异常退出,先退出登录
					//从已登录用户数据表中,将用户名对应的项删除
					bzero(sql, sizeof(sql));
					char *errmsg = NULL;
					snprintf(sql,sizeof(sql),"delete from loadedUsr where id=\'%s\';",usrname);

					if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
						printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
						break;	
					}
					//将usrname这个字符串清空
					bzero(usrname,sizeof(usrname));

				}else if(1 == res){
					//说明用户已经退出登录
					bzero(usrname,sizeof(usrname));
				}		
			}

			//结束函数
			return;

		}else if(4 == *operatorPtr){
			//查询
			//接收到要查询的英文单词,需要在dict数据表中查找,没找到的话也应该返回一个数据提示
			bzero(sql, sizeof(sql));

			char **result = NULL;
			int row = 0;
			int col = 0;
			char *errmsg = NULL;
			int flag = 0;

			snprintf(sql,sizeof(sql),"select ENGLISH,TRANSLATION from dict where ENGLISH=\'%s\';",dataPtr);

			if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
				printf("%d:sqlite3_get_table error\n",__LINE__);
				printf("%s\n",strerror(res));
				break;
			}

			*operatorPtr = 7;
			if(strcmp(*(result+2),dataPtr)==0){
				//如果查找到的因为原型与发送来的相同,说明要找的单词存在
				snprintf(dataPtr,128,"%s\t%s",*(result+2),*(result+3));

				//将对应的英文及其翻译还有当时时间记录
				bzero(sql, sizeof(sql));

				snprintf(sql, sizeof(sql),"insert into %shis values(\"%s\", \"%s\",CURRENT_TIMESTAMP);",usrname, *(result+2), *(result+3));

				if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
					printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
					break;	
				}

			}else{
				//否则不存在,发送一个反馈的包
				strcpy(dataPtr,"抱歉该单词还未收录");
			}
			

		}else if(5 == *operatorPtr){
			//历史记录
			bzero(sql, sizeof(sql));

			char **result = NULL;
			int row = 0;
			int col = 0;
			char *errmsg = NULL;
			int flag = 0;

			bzero(sql, sizeof(sql));

			snprintf(sql,sizeof(sql),"select * from %shis;",usrname);
			//printf("%s\n",sql);

			if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
				printf("%d:sqlite3_get_table error\n",__LINE__);
				printf("%s\n",strerror(res));
				break;
			}

			*operatorPtr = 7;
			for(int i=col; i<=row*col; i+=col){
				*operatorPtr = 7;
				snprintf(dataPtr,128,"%s\t%s\t%s",*(result+i),*(result+i+1),*(result+i+2));
				//发送返回的数据包
				send(newfd, buf, sizeof(buf), 0);
				bzero(dataPtr,128);
			}
		}else if(6 == *operatorPtr){
			//退出登录
			//从已登录用户数据表中,将用户名对应的项删除
			bzero(sql, sizeof(sql));
			char *errmsg = NULL;
			snprintf(sql,sizeof(sql),"delete from loadedUsr where id=\'%s\';",usrname);

			if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
				printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
				break;	
			}
			//将usrname这个字符串清空
			bzero(usrname,sizeof(usrname));
			*operatorPtr = 7;
			strcpy(dataPtr,"账号成功退出登录");
		}else{
		}
		//发送返回的数据包
		send(newfd, buf, sizeof(buf), 0);
	}

}

//查询用户名是否重复函数
int usrname_not_reuse(sqlite3 *db, const char *usrname, const char *tablename){
	char **res = NULL;
	int row = 0;
	int col = 0;
	char *errmsg = NULL;

	//调用查询函数
	char sql[128] = " ";
	snprintf(sql,sizeof(sql),"select id from %s;",tablename);

	if(sqlite3_get_table(db, sql, &res, &row, &col, &errmsg)!=0){
		printf("%d:sqlite3_get_table error\n",__LINE__);
		return -1;
	}
	
	//遍历比较,第0行是项的名,所以从1开始
	for(int i=1; i<=row; i++){
		if(strcmp(*(res+i),usrname) == 0){
			//满足条件说明用户名已存在,返回0
			return 0;
		}
	}

	//遍历到结束,说明该用户名还未存在,返回1
	return 1;
}

//TCP客户端搭建函数
int TCP_cli_set(){
	int cfd;
	if((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		ERR_MSG("socket error");
		return -1;
	}

	int optval = 1;
	//允许端口快速复用
	if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))<0){
		ERR_MSG("setsockopt error");
		return -1;
	}

	//获取地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(SERIP);

	//连接
	if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin))<0){
		ERR_MSG("connect error");
		return -1;
	}

	printf("客户端搭建成功\n");
	return cfd;
}

//客户端中的操作
void cli_operate(int cfd){
	if(cfd<0){
		printf("文件描述符有误\n");
		return;
	}
	//菜单
	int opt = 0;
	char buf[150] = " ";
	unsigned short *operatorPtr = (unsigned short *)buf;
	//记录用户名
	char id[20] = " ";
	//记录用户名长度
	int idlen = 0;
	//记录已登录用户的用户名
	char loadedid[20] = " ";
	int loadedidlen = 0;
	//记录密码
	char passwd[20] = " ";
	//记录密码长度
	int passwdlen = 0;
	while(1){
		bzero(buf,sizeof(buf));
		bzero(id,sizeof(id));
		bzero(passwd,sizeof(passwd));

		system("clear");
		printf("****************************\n");
		printf("**********电子词典**********\n");
		printf("***********1.注册***********\n");
		printf("***********2.登录***********\n");
		printf("***********3.退出***********\n");
		printf("****************************\n");
		printf("请输入>>");
		scanf("%d",&opt);

		if(1 == opt){
			//注册
			*operatorPtr = 1;
			printf("请输入要注册的用户名:");
			while(1){
				scanf("%s",id);
				while(getchar()!=10);
				//记录账号长度,保证长度符合要求才能跳出循环
				idlen = strlen(id);
				if(idlen>0&&idlen<20){
					break;
				}
				printf("账号长度请不要超过20,请重新输入:");
			}
			printf("请输入密码:");
			while(1){
				scanf("%s",passwd);
				while(getchar()!=10);
				//记录密码长度,保证长度符合要求才能跳出循环
				passwdlen = strlen(passwd);
				if(passwdlen<20&&passwdlen>0){
					break;
				}
				printf("密码长度请不要超过20,请重新输入:");
			}
			//将账号写到对应位置
			strcpy(buf+2,id);
			//将密码写到对应位置
			strcpy(buf+3+idlen,passwd);

			send(cfd, buf, sizeof(buf), 0);
			recv(cfd, buf, sizeof(buf), 0);
			printf("%s\n",buf+3+idlen);

		}else if(2 == opt){
			//登录
			*operatorPtr = 2;
			printf("请输入要登录的用户名:");
			while(1){
				scanf("%s",id);
				while(getchar()!=10);
				//记录账号长度,保证长度符合要求才能跳出循环
				idlen = strlen(id);
				if(idlen>0&&idlen<20){
					break;
				}
				printf("账号长度请不要超过20,请重新输入:");
			}
			printf("请输入密码:");
			while(1){
				scanf("%s",passwd);
				while(getchar()!=10);
				//记录密码长度,保证长度符合要求才能跳出循环
				passwdlen = strlen(passwd);
				if(passwdlen<20&&passwdlen>0){
					break;
				}
				printf("密码长度请不要超过20,请重新输入:");
			}
			//将账号写到对应位置
			strcpy(buf+2,id);
			//将密码写到对应位置
			strcpy(buf+3+idlen,passwd);

			send(cfd, buf, sizeof(buf), 0);
			recv(cfd, buf, sizeof(buf), 0);
			printf("%s\n",buf+3+idlen);
			if(strcmp(buf+3+idlen,"登录成功")==0){
				strcpy(loadedid,id);
				loadedidlen = idlen;
				//将账号写到对应位置
				strcpy(buf+2,loadedid);

				printf("输入任意字符刷新>>");
				getchar();
				while(getchar()!=10);

				while(1){
					strcpy(buf+2,loadedid);
					system("clear");
					printf("****************************\n");
					printf("**********电子词典**********\n");
					printf("*****usr:%s*****\n",loadedid);
					printf("***********1.查询***********\n");
					printf("*********2.历史记录*********\n");
					printf("*********3.退出登录*********\n");
					printf("****************************\n");
					printf("请输入>>");
					scanf("%d",&opt);

					if(1 == opt){
						//查找
						*operatorPtr = 4;
						printf("请输入要查找的单词>>");
						scanf("%s",buf+3+loadedidlen);

						send(cfd, buf, sizeof(buf), 0);
						recv(cfd, buf, sizeof(buf), 0);
						printf("%s\n",buf+3+loadedidlen);
					}else if(2 == opt){
						//历史记录
						*operatorPtr = 5;
						//由于已经将用户id写入buf包中,只需将包发送即可
						send(cfd, buf, sizeof(buf), 0);
						recv(cfd, buf, sizeof(buf), 0);
						char *dataPtr = buf+3+loadedidlen;
						//应该循环接收,那么服务器发包应该在数据区写入结束标志
						while(*dataPtr){
							printf("%s\n",dataPtr);
							recv(cfd, buf, sizeof(buf), 0);
						}
					}else if(3 == opt){
						//退出登录
						//发送一个操作码为6的空包,向服务器提示该账号要退出登录
						//将记录已登录id的字符串清空,用于存储下一个登录用户id
						*operatorPtr = 6;
						send(cfd, buf, sizeof(buf), 0);

						recv(cfd, buf, sizeof(buf), 0);
						printf("%s\n",buf+3+loadedidlen);

						bzero(loadedid,sizeof(loadedid));
						loadedidlen = 0;
						break;
					}else{
						printf("输入不规范,亲人两行泪,请重新输入\n");
					}

					printf("输入任意字符刷新>>");
					getchar();
					while(getchar()!=10);
					bzero(buf,sizeof(buf));
				}
			}
		}else if(3 == opt){
			//退出
			//发送一个操作码为3的空包
			*operatorPtr = 3;
			send(cfd, buf, sizeof(buf), 0);
			break;
		}else{
			printf("输入不规范,亲人两行泪,请重新输入\n");
		}

		printf("输入任意字符刷新>>");
		getchar();
		while(getchar()!=10);
	}



}
服务器测试文件:serDict.c:
#include<myhead.h>
#include<sqlite3.h>
#include "dict.h"

int main(int argc, const char *argv[])
{
	//回收子进程
	signal(SIGCHLD,handler);

	//打开数据库
	sqlite3 * db;
	if(sqlite3_open("./dict.db", &db) != SQLITE_OK){
		printf("%d:sqlite3_open error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;
	}

	//初始化数据库,完成词典数据表的重载以及用户信息数据库的导入
	dict_init(db);

	struct sockaddr_in sin;
	socklen_t addrlen = sizeof(sin);
	int sfd;
	if((sfd = TCP_ser_set(&sin))<0){
		printf("服务器搭建失败");
		return -1;
	}

	pid_t pid;
	int newfd;
	while(1){
		if((newfd = accept(sfd,  (struct sockaddr*)&sin, &addrlen))<0){
			ERR_MSG("accept error");
			return 0;
		}

		pid = fork();
		if(pid == 0){		
			close(sfd);
		
			printf("这是子进程\n");
			child_operate(newfd, db);

			close(newfd);
			//关闭数据库
			if(sqlite3_close(db) != SQLITE_OK){
				printf("%d:sqlite3_close error %s\n",__LINE__, sqlite3_errmsg(db));
				return -1;		
			}
			exit(EXIT_SUCCESS);
		}
		close(newfd);

	}


	//关闭数据库
	if(sqlite3_close(db) != SQLITE_OK){
		printf("%d:sqlite3_close error %s\n",__LINE__, sqlite3_errmsg(db));
		return -1;		
	}
	close(sfd);
	return 0;
}
客户端测试文件:cliDict.c:
#include<myhead.h>
#include<sqlite3.h>
#include "dict.h"

int cfd;

//用户按下ctrl+c后给服务器发一个退出登录的包
void handlerINT(int signum){
	char buf[150] = " ";
	unsigned short *operatorPtr = (unsigned short*)buf;
	//发送一个操作码为3的空包,向服务器提示该账号要退出,退出功能中包含了退出登录
	*operatorPtr = 3;
	send(cfd, buf, sizeof(buf), 0);
}

int main(int argc, const char *argv[])
{
	//用户按下ctrl+c后给服务器发一个退出登录的包
	signal(2,handlerINT);

	//调用TCP客户端搭建函数
	if((cfd = TCP_cli_set())<0){
		printf("客户端搭建失败\n");
	}

	cli_operate(cfd);

	
	close(cfd);	
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值