基于文件IO、网络编程、sqlite3数据库——电子词典
一、电子词典主功能介绍
1.注册:客户端发起注册请求,服务器检测到请求后从用户数据库中遍历是否有该账号存在,若没有则直接注册;若存在该账号则注册失败;
2.登录:客户端发起登录请求,服务器检测到登录请求后从用户数据库中遍历用户名和密码是否匹配,匹配成功则登录成功;匹配失败则登录失败;
3.查单词:客户端发起查单词请求,服务器检测到请求后从单词数据库遍历是否存在,若存在则返回单词意思给客户端,并把单词及单词意思插入到历史记录数据库中;不存在则返回查找失败的信息;
4.历史记录:客户端发起历史记录查询请求,服务器检测到请求后从历史记录数据库中将所有信息返回给客户端
二、电子词典文件说明
![](https://img-blog.csdnimg.cn/img_convert/c00983388bc0e37d2fbc7106eb206172.png)
1.dict.txt——为单词表,程序运行前需要将单词表dict.txt中数据插入到 word.db单词数据库中。
2.word.db——为单词数据库,客户端查找单词时,服务器从word.db数据库中遍历该单词的信息,并回发给客户端。
3.user.db——为用户数据库,用于存放用户信息,注册时将用户信息存入user.db,登录时从user.db中遍历并判断用户名和密码是否匹配(注册时还须从user.db数据库中遍历注册的用户名是否存在)
4.history.db——为历史记录数据库,用于存放查询成功的单词信息,用户调用查询历史记录是服务器将所有信息回发给客户端
三、项目思路
服务器采用TCP多进程方式,可同时处理多个客户端。主进程处理客户端的连接,子进程处理服务器与客户端之间的通信。
定义一个结构体用于客户端与服务器之间的信息发送和接受。
typedef struct
{
int type;
char name[50];
char data[256];
}MSG;
创建数据库前检查是否存在单词表,不存在则导入单词表。
判断是否存在所需的数据库,若不存在则创建数据库,创建数据库时将数据库中的表创建好,并将单词表数据导入到单词数据库中。
客户端发起注册请求时,服务器从用户数据库查询是否存在用户名,若没有则将用户信息插入到用户数据库中。若存在则返回给客户端用户已存在的信息,进行重新注册。
客户端发起登录请求时,服务器从用于数据库查找用户名,并判断密码是否正确,如两者都符合则登录成功,返回登录成功信息。若不符合则返回登录失败信息给客户端。
登录成功后用户可发起查询单词请求,服务器从客户端接受查询的单词信息,从单词数据库遍历符合的单词,将信息返回给客户端,并将查询的单词及解释插入到历史记录数据库中。
用户发起历史数据记录请求时,服务器将历史记录数据库的所有单词信息发送给客户端。
服务器返回成功的信息中tpye都为T,返回失败的信息中type都为F
客户端退出,服务器将退出的子进程资源回收
四、效果展示
![](https://img-blog.csdnimg.cn/img_convert/2ca71c842638f3a5fc2c1a3ff5c450be.png)
![](https://img-blog.csdnimg.cn/img_convert/670a382909d051cf081505f1decbb158.png)
![](https://img-blog.csdnimg.cn/img_convert/8f317b6f6b2a82c78834a4c4dda6a5f5.png)
![](https://img-blog.csdnimg.cn/img_convert/829572067468ba282a80d460ae67d902.png)
![](https://img-blog.csdnimg.cn/img_convert/532206117d60b5ec14a3ea5c3b2abdd1.png)
![](https://img-blog.csdnimg.cn/img_convert/4b8c8ff8feb50e2011a0cbdf37f790f0.png)
![](https://img-blog.csdnimg.cn/img_convert/c5a20d7b402e95f0d7879efa9c9c756a.png)
![](https://img-blog.csdnimg.cn/img_convert/fcd8b92114309307b5cb86fb6586e464.png)
五、代码
服务器搭建
(温馨提示:电子词典名纯属搞笑,请勿当真;因为本人没有这个能力😂)
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/socket.h>
#include <sqlite3.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <sqlite3.h>
#include <stdlib.h>
#define IP "0"
#define PORT 6666
#define BACKLOG 1024
/*---------------
R 注册
L 登陆
S 查询单词
H 查历史记录
Q 退出
----------------*/
/*======================================有道翻译增强版1.0=====================================*/
/*****************************************多进程服务器**************************************/
typedef struct //接受发送结构体
{
int type;
char name[50];
char data[256];
}MSG;
int init_server(char *ip,int port,int backlog); //初始化服务器
void signal_hander(int sig); //回收退出的进程
void sqlite3_exist(); //判断数据库是否存在,不存在则创建(单词数据库,用户数据库,历史记录数据库)
int word_sqlite3_create(); //创建单词数据库
int user_sqlite3_create(); //创建用户数据库
int history_sqlite3_create(); //创建历史记录库
int word_insert(sqlite3 *db,char *buf); //插入单词到单词表中
int do_client(int connfd,struct in_addr ip,uint16_t port); //处理客户端
int do_register(int connfd,char *name,char *data,sqlite3* db_user); //注册
int do_login(int connfd,char *name,char *data,sqlite3 *db_user,char *nameBuf); //登陆
int search_word(int connfd,char *nameBuf,char *name,sqlite3 *db_word,sqlite3 *db_history); //查单词
int do_history(int connfd,char *nameBuf,sqlite3 *db_history); //查历史记录
/*****************************************主函数****************************************/
int main(int argc, char *argv[])
{
signal(SIGCHLD,signal_hander); //注册SIGCHLD信号
//创建数据库
sqlite3_exist();
//初始化 ip port
int listenfd = init_server(IP,PORT,BACKLOG);
if(-1 == listenfd)
{
printf("init_server failed!\n");
exit(-1);
}
while(1)
{
printf("请等待连接!\n");
//accept
struct sockaddr_in client_addr = {0};
socklen_t len = sizeof(client_addr);
int connfd = accept(listenfd,(struct sockaddr *)&client_addr,&len);
if(-1 == connfd)
{
if(errno == EINTR) //如果阻塞 跳过本次循环 执行下一次监听
{
continue;
}
else
{
perror("accept");
exit(-1);
}
}
printf("客户端:(ip:%s port:%d)已连接\n",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));//打印连接客户端信息
pid_t pid; //进程号
pid = fork();
if(-1 == pid)
{
perror("fork");
exit(-1);
}
else if(pid == 0) /*子进程处理与客户端发送接受信息 关闭监听套接字*/
{
close(listenfd);
//与客户端通信处理
do_client(connfd,client_addr.sin_addr,client_addr.sin_port);
}
else /*父进程处理客户端连接 关闭通信套接字*/
{
close(connfd);
continue;
}
}
close(listenfd); //所有子进程结束 关闭监听套接字 结束服务器
return 0;
}
/*****************************************功能模块******************************************/
/**********初始化服务器***********/
int init_server(char *ip,int port,int backlog)
{
//socket
int listenfd = socket(PF_INET,SOCK_STREAM,0);
if(-1 == listenfd)
{
perror("socket");
exit(-1);
}
//init port ip
struct sockaddr_in serveraddr = {
.sin_family = PF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = inet_addr(ip)
};
//允许重用本地地址和端口
int opt = 1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
//bind
int ret = bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(-1 == ret)
{
perror("bind");
exit(-1);
}
//linstn
ret = listen(listenfd,backlog);
if(-1 == ret)
{
perror("listen");
exit(-1);
}
return listenfd;
}
/**********回收退出的进程***********/
void signal_hander(int sig)
{
printf("回收僵尸进程!\n");
sleep(1);
while(waitpid(-1,NULL,WNOHANG) > 0);
}
/***********判断数据库是否存在***********/
void sqlite3_exist()
{
//判断单词数据库是否存在 不存在则创建
if(access("./word.db",F_OK) == 0)
{
printf("\033[01;34m单词数据库已存在!\033[0m\n");
}
else //单词数据库不存在先判断单词表文本是否存在
{
printf("\033[01;34m单词数据库不存在!\033[0m\n");
sleep(1);
if(access("./dict.txt",F_OK) == -1)
{
printf("\033[01;34m单词表不存在!\033[0m\n");//单词表不存在则退出
return;
}
else //单词表存在则插入单词数据库
{
printf("\033[01;34m单词数据库创建中......!\033[0m\n");
//创建单词表
int ret = word_sqlite3_create();
if(-1 == ret)
{
printf("world_sqlite3_create failed\n");
return;
}
printf("\033[01;34m单词数据库创建成功!\033[0m\n");
}
}
sleep(1);
//判断用户数据库是否存在 不存在则创建
if(access("./user.db",F_OK) == 0)
{
printf("\033[01;33m用户数据库已存在!\033[0m\n");
}
else
{
printf("\033[01;33m用户数据库不存在!\033[0m\n");
sleep(1);
printf("\033[01;33m用户数据库创建中......!\033[0m\n");
//创建用户表
int ret = user_sqlite3_create();
if(-1 == ret)
{
printf("user_sqlite3__create failed\n");
return;
}
sleep(1);
printf("\033[01;33m用户数据库创建成功!\033[0m\n");
}
sleep(1);
//判断历史记录数据库是否存在 不存在则创建
if(access("./history.db",F_OK) == 0)
{
printf("\033[01;32m历史记录库已存在!\033[0m\n");
return;
}
else
{
printf("\033[01;32m历史记录库不存在!\033[0m\n");
sleep(1);
printf("\033[01;32m历史记录库创建中......!\033[0m\n");
//创建历史记录表
int ret = history_sqlite3_create();
if(-1 == ret)
{
printf("history_sqlite3_create failed\n");
return;
}
sleep(1);
printf("\033[01;32m历史记录库创建成功!\033[0m\n");
}
sleep(1);
return;
}
/**********创建单词数据库**********/
int word_sqlite3_create()
{
FILE *fp = fopen("./dict.txt","r"); //以只读方式打开单词表
if(NULL == fp)
{
perror("open");
exit(-1);
}
sqlite3 *db_word; //操作单词数据库的句柄
int ret = sqlite3_open("./word.db",&db_word);
if(ret != SQLITE_OK)
{
perror("sqlite3_open");
exit(-1);
}
//创建单词表
char *errmsg; //接收返回的错误信息
char sql[256] = "create table if not exists word(word char, mean char);";
ret = sqlite3_exec(db_word,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
char buf[BUFSIZ] = {0};
//读取单词数据到表中
while(1)
{
bzero(buf,0); //清空数组
if(NULL == fgets(buf,BUFSIZ,fp)) //读取一行数据
{
break;
}
buf[strlen(buf)-1] = 0; //去除 \n
int ret = word_insert(db_word,buf);
if(-1 ==ret)
{
//printf("%s\n",buf);
printf("word_insert failed\n");
}
}
sqlite3_close(db_word);
fclose(fp);
return 0;
}
/**********创建用户数据库**********/
int user_sqlite3_create()
{
sqlite3 *db_user; //操作单词数据库的句柄
int ret = sqlite3_open("./user.db",&db_user);
if(ret != SQLITE_OK)
{
perror("sqlite3_open");
exit(-1);
}
//创建用户表
char *errmsg; //接收返回的错误信息
char sql[256] = "create table if not exists user(id char, password char);";
ret = sqlite3_exec(db_user,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
sqlite3_close(db_user);
return 0;
}
/**********创建历史记录库**********/
int history_sqlite3_create()
{
sqlite3 *db_user; //操作单词数据库的句柄
int ret = sqlite3_open("./history.db",&db_user);
if(ret != SQLITE_OK)
{
perror("sqlite3_open");
exit(-1);
}
//创建用户表
char *errmsg; //接收返回的错误信息
char sql[256] = "create table if not exists history(data char);";
ret = sqlite3_exec(db_user,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
sqlite3_close(db_user);
return 0;
}
/*单词表插入数据库*/
int word_insert(sqlite3 *db,char *buf)
{
char word_buf[50] = {0};
char mean_buf[256] = {0};
char sql[512] = {0};
char *errmsg;
for(int i=0;buf[i+1]!=0;i++)
{
if(buf[i]!=' ' && buf[i+1]==' ' && buf[i+2]==' ')
{
strncpy(word_buf,buf,i+1); //获取单词
}
else if(buf[i]==' ' && buf[i+1]==' ' && buf[i+2]!=' ')
{
strcpy(mean_buf,buf); //获取意思
break;
}
}
//插入到表中
sprintf(sql,"insert into word values('%s','%s');",word_buf,mean_buf);
int ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
bzero(word_buf,0);
bzero(mean_buf,0);
bzero(sql,0);
return 0;
//exit(0);
}
/**********处理客户端**********/
int do_client(int connfd,struct in_addr ip,uint16_t port)
{
//打开单词数据库
sqlite3 *db_word;
int ret = sqlite3_open("./word.db",&db_word);
if(ret != SQLITE_OK )
{
perror("sqlite3_open");
exit(-1);
}
//打开用户数据库
sqlite3 *db_user;
ret = sqlite3_open("./user.db",&db_user);
if(ret != SQLITE_OK )
{
perror("sqlite3_open");
exit(-1);
}
//打开历史记录库
sqlite3 *db_history;
ret = sqlite3_open("./history.db",&db_history);
if(ret != SQLITE_OK )
{
perror("sqlite3_open");
exit(-1);
}
MSG buf;
char nameBuf[50] = {0}; //接受登陆成功后的用户名
while(1)
{
memset(&buf,0,sizeof(buf));
ret = recv(connfd,&buf,sizeof(buf),0);
if(ret < 0)
{
perror("recv");
close(connfd);
exit(-1);
}
else if(ret == 0)//用户退出
{
//关闭通信套接字
printf("客户端[ip:%s port:%d]已退出 ",inet_ntoa(ip),ntohs(port));
close(connfd);
//关闭数据库
sqlite3_close(db_word);
sqlite3_close(db_user);
sqlite3_close(db_history);
exit(-1);
}
switch(buf.type)
{
case 'R':
do_register(connfd,buf.name,buf.data,db_user); //注册
break;
case 'L':
do_login(connfd,buf.name,buf.data,db_user,nameBuf); //登陆
break;
case 'S':
search_word(connfd,nameBuf,buf.name,db_word,db_history); //查单词
break;
case 'H':
do_history(connfd,nameBuf,db_history); //历史记录
break;
default:
printf("客户端[%s]错误信息!\n",nameBuf);
}
}
exit(0);
}
/**********注册**********/
int do_register(int connfd,char *name,char *data,sqlite3* db_user)
{
printf("用户发起注册请求\n");
MSG buf1;
memset(&buf1,0,sizeof(buf1));
char sql[256] = {0};
char *errmsg;
char **dbresult;
int nrow = 0;
int ncol = 0;
//查询用户表中是否有注册用户名
sprintf(sql,"select * from user where id='%s';",name);
int ret = sqlite3_get_table(db_user,sql,&dbresult,&nrow,&ncol,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_get_table");
exit(-1);
}
//用户已存在
if(nrow != 0) //没有查询到接受用户的用户名
{
printf("用户名[%s]存在\n",name);
buf1.type = 'F'; //注册失败返回 F
strcpy(buf1.data,"用户名已存在!请重新注册[输入R后回车]");
if(send(connfd,&buf1,sizeof(buf1),0) < 0) //返回注册失败信息给客户端
{
perror("send");
exit(-1);
}
}
//用户不存在,插入到用户数据表中
if(nrow == 0)
{
memset(&sql,0,sizeof(sql));
memset(&buf1,0,sizeof(buf1));
sprintf(sql,"insert into user values('%s','%s');",name,data);
ret = sqlite3_exec(db_user,sql,NULL,NULL,&errmsg);
if(ret !=SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
strcpy(buf1.data,"注册成功!请登陆[输入L]");
buf1.type = 'T'; //注册成功返回 T
if(send(connfd,&buf1,sizeof(buf1),0) < 0) //返回注册成功信息给客户端
{
perror("send");
exit(-1);
}
printf("用户[%s]注册成功\n",name);
}
//释放获取的空间
sqlite3_free_table(dbresult);
dbresult = NULL;
return 0;
}
/**********登陆***********/
int do_login(int connfd,char *name,char *data,sqlite3 *db_user,char *nameBuf)
{
printf("用户[%s]发起登陆请求\n",name);
MSG buf1;
memset(&buf1,0,sizeof(buf1));
char sql[256] = {0};
char *errmsg;
char **dbresult;
int nrow = 0;
int ncol = 0;
//查询用户表中是否有注册用户名
sprintf(sql,"select * from user where id='%s' and password='%s';",name,data);
int ret = sqlite3_get_table(db_user,sql,&dbresult,&nrow,&ncol,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_get_table");
exit(-1);
}
//帐号密码与用户数据库匹配 登陆成功
if(nrow != 0)
{
buf1.type = 'T'; //登陆成功返回T
strcpy(buf1.data,"登陆成功");
strcpy(nameBuf,name);// 接受登陆成功的用户名
printf("用户[%s]登陆成功\n",name);
if(send(connfd,&buf1,sizeof(buf1),0) < 0) // 返回登陆信息
{
perror("send");
exit(-1);
}
}
//帐号密码与用户数据库不匹配 登陆失败
if(nrow == 0)
{
buf1.type = 'F'; //登陆失败返回F
strcpy(buf1.data,"用户或密码错误!请重新登陆[输入L后回车]");
if(send(connfd,&buf1,sizeof(buf1),0) < 0) //返回登陆信息
{
perror("send");
exit(-1);
}
printf("用户[%s]登陆失败\n",name);
}
//获取释放的空间
sqlite3_free_table(dbresult);
dbresult = NULL;
return 0;
}
/***********查单词**********/
int search_word(int connfd,char *nameBuf,char *name,sqlite3 *db_word,sqlite3 *db_history)
{ // 传参中 char *name 是存放客户端输入查询的的单词
printf("客户端[%s]发起单词查询请求\n",nameBuf);
MSG buf;
memset(&buf,0,sizeof(buf));
char sql[256] = {0};
char **result;
int ncol = 0;
int nrow = 0;
char *errmsg;
sprintf(sql,"select * from word where word='%s';",name);
int ret = sqlite3_get_table(db_word,sql,&result,&nrow,&ncol,&errmsg);//按条件查找单词
if(ret != SQLITE_OK)
{
perror("sqlite3_get_table");
exit(-1);
}
//查询失败
if(nrow == 0)
{
buf.type = 'F'; //查询失败返回F
strcpy(buf.data,"没有查询到此单词!请重新输入");
if(send(connfd,&buf,sizeof(buf),0) < 0) //返回查寻单词失败的信息
{
perror("send");
exit(-1);
}
printf("用户[%s]查找单词[%s]失败\n",nameBuf,name);
printf("\033[01;31m温馨提示:单词库没有次单词!建议新增此单词到数据库\033[0m\n");
}
//查找成功
if(nrow != 0)
{
for(int i=ncol;i<(nrow+1)*ncol;i+=2)
{
if(strcmp(name,result[i]) == 0)
{
strcpy(buf.data,result[i+1]); //将查找的单词意思放入buf.data中
strcpy(buf.name,result[i]); //将查找的单词存方在buf.name中
//将查询结果存入历史数据库中
char sql1[256] = {0};
sprintf(sql1,"insert into history values('%s');",result[i+1]);
ret = sqlite3_exec(db_history,sql1,NULL,NULL,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_exec");
exit(-1);
}
break;
}
}
buf.type = 'T'; //查找成功返回T
if(send(connfd,&buf,sizeof(buf),0) < 0) //返回查寻单词失败的信息
{
perror("send");
exit(-1);
}
printf("用户[%s]查找单词[%s]成功\n",nameBuf,name);
}
//释放获取的空间
sqlite3_free_table(result);
result = NULL;
return 0;
}
/**********查历史记录**********/
int do_history(int connfd,char *nameBuf,sqlite3 *db_history)
{
printf("用户[%s]发起历史记录查询请求\n",nameBuf);
char history_buf[10240] = {0}; //存放查询历史记录的数组(大约存放300条历史记录)
MSG buf;
char sql[256] = {0};
char **result;
char *errmsg;
int nrow = 0;
int ncol = 0;
sprintf(sql,"select * from history;");
int ret = sqlite3_get_table(db_history,sql,&result,&nrow,&ncol,&errmsg);
if(ret != SQLITE_OK)
{
perror("sqlite3_get_table");
exit(-1);
}
if(nrow != 0) //查询到有历史记录
{
printf("用户[%s]查询历史记录成功\n",nameBuf);
for(int i=ncol;i<nrow+1;i++)
{
strcat(history_buf,result[i]);
strcat(history_buf,"\n");
}
if(send(connfd,history_buf,sizeof(history_buf),0) < 0 ) //发送历史记录信息到客户端
{
perror("send");
exit(-1);
}
}
else if(nrow == 0) //没有查询到历史记录
{
printf("用户[%s]未查询到历史记录\n",nameBuf);
strcpy(history_buf,"F");
if(send(connfd,history_buf,sizeof(history_buf),0) < 0) //返回查寻历史记录失败的信息
{
perror("send");
exit(-1);
}
}
//释放获取的空间
sqlite3_free_table(result);
result = NULL;
return 0;
}
2.客户端搭建
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <strings.h>
#define IP "0"
#define PORT 6666
/*===================================有道翻增强解版1.0====================================*/
/****************************************用户端*****************************************/
typedef struct //接受发送结构体
{
int type;
char name[50];
char data[256];
}MSG;
int client_init(char *,int );//初始化客户端
int do_register(int connfd); //注册
int do_login(int connfd); //登陆
int search_word(int connfd); //查单词
int do_history(int connfd); //历史记录
int do_quit(); // 退出
void do_upLevel(); //返回上一界面(登陆界面)
void desktop1(); //界面1
void desktop2(); //界面2
/*******************************主函数******************************/
int main(int argc, char *argv[])
{
//初始化
int connfd = client_init(IP,PORT);
desktop1(); //主界面
char choose;
char c;
while(1)
{
int ret;
printf("\033[01;32m请选择功能:\033[0m");
setbuf(stdin,NULL); //关闭缓存区
choose = getchar();
c = getchar(); //接受回车
switch(choose)
{
case 'R':
do_register(connfd); //注册
break;
case 'L':
do_login(connfd); //登陆
break;
case 'S':
search_word(connfd); //查单词
break;
case 'H':
do_history(connfd); //查历史记录
break;
case 'Q':
ret = do_quit(); //退出
if(ret == 0)
return 0;
break;
case 'q':
do_upLevel();//返回上一级
break;
}
}
close(connfd);
return 0;
}
/*******************************功能模块*******************************/
/**********界面打印**********/
void desktop1()
{
printf("\t\t________________________________________\n");
printf("\t\t| 有道翻译增强版 |\n");
printf("\t\t| |\n");
printf("\t\t|欢迎来有道翻译增强版! |\n");
printf("\t\t| |\n");
printf("\t\t| 开发者:im 林林哟 |\n");
printf("\t\t| 版本号:1.0.0 |\n");
printf("\t\t| 功 能: |\n");
printf("\t\t| [\033[01;32mR\033[0m] \033[01;32m注册\033[0m |\n");
printf("\t\t| [\033[01;33mL\033[0m] \033[01;33m登陆\033[0m |\n");
printf("\t\t| [\033[01;34mQ\033[0m] \033[01;34m退出\033[0m |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t|(温馨提示:2.0.0即将发布,敬请期待!) |\n");
printf("\t\t|______________________________________|\n");
}
void desktop2()
{
printf("\t\t________________________________________\n");
printf("\t\t| 有道翻译增强版 |\n");
printf("\t\t| |\n");
printf("\t\t|欢迎来到单词查询系统! |\n");
printf("\t\t| |\n");
printf("\t\t| 功 能: |\n");
printf("\t\t| [\033[01;32mS\033[0m] \033[01;32m查询单词\033[0m |\n");
printf("\t\t| [\033[01;33mH\033[0m] \033[01;33m历史记录\033[0m |\n");
printf("\t\t| [\033[01;34mq\033[0m] \033[01;34m返回上级\033[0m |\n");
printf("\t\t| |\n");
printf("\t\t| |\n");
printf("\t\t|(温馨提示:2.0.0即将发布,敬请期待) |\n");
printf("\t\t|______________________________________|\n");
}
/**********退出**********/
int do_quit()
{
while(1)
{
printf("\033[01;31m警告\033[0m : 程序正在运行,是否退出![Y/N]:");
setbuf(stdin,NULL); //关闭缓存区
char var;
char c;
var = getchar();
c = getchar(); //接受回车
if(var == 'Y' || var == 'y')
{
return 0;
}
else if(var == 'N' || var == 'n')
{
return 1;
}
}
}
/**********返回上一级**********/
void do_upLevel()
{
char var;
char c;
while(1)
{
printf("\033[01;31m警告\033[0m : 是否回到登陆界面[Y/N]:");
setbuf(stdin,NULL); //关闭缓存区
var = getchar();
c = getchar(); //接受回车
if(var == 'Y' || var == 'y')
{
system("clear");
desktop1();
return;
}
else if(var == 'N' || 'n')
{
return;
}
}
}
/**********初始化客户端**********/
int client_init(char *ip,int port)
{
//1.socket
int connfd = socket(PF_INET,SOCK_STREAM,0);
if(-1 == connfd)
{
perror("socket");
return -1;
}
//2.ip port init
struct sockaddr_in cliaddr = {
.sin_family = PF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = inet_addr(ip)
};
//3.connect
int ret = connect(connfd,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
if(-1 == ret)
{
perror("connect");
return -1;
}
return connfd;
}
/**********注册**********/
int do_register(int connfd)
{
MSG buf;
MSG buf1;
char id_buf[50] = {0};
char password_buf[50] = {0};
printf("\033[01;32m请输入注册账号:\033[0m");
scanf("%s",id_buf);
//fgets(id_buf,50,stdin);
//id_buf[strlen(id_buf) - 1] = '\0';//消除 \n
printf("\033[01;32m请输入注册密码:\033[0m");
scanf("%s",password_buf);
//fgets(password_buf,50,stdin);
//password_buf[strlen(password_buf) - 1] = '\0';//消除 \n
buf1.type = 'R';
sprintf(buf1.name,"%s",id_buf);
sprintf(buf1.data,"%s",password_buf);
if(send(connfd,&buf1,sizeof(buf1),0) < 0) //发送注册信息到服务器
{
perror("send");
return -1;
}
if(recv(connfd,&buf,sizeof(buf),0) < 0) //从服务器接受是否注册成功信息
{
perror("recv");
return -1;
}
if(buf.type == 'T') //返回 T 注册成功
{
printf("%s\n",buf.data);
}
if(buf.type == 'F') //返回 F 注册失败
{
printf("\033[01;31m%s\033[0m\n",buf.data);
}
return 0;
}
/**********登陆**********/
int do_login(int connfd)
{
MSG buf;
MSG buf1;
char id_buf[50] = {0};
char password_buf[50] = {0};
printf("\033[01;33m请输入登陆的账号:\033[0m");
scanf("%s",id_buf);
printf("\033[01;33m请输入登陆的密码:\033[0m");
scanf("%s",password_buf);
buf1.type = 'L';
sprintf(buf1.name,"%s",id_buf);
sprintf(buf1.data,"%s",password_buf);
if(send(connfd,&buf1,sizeof(buf1),0) < 0) //发送登陆信息到服务器
{
perror("send");
return -1;
}
if(recv(connfd,&buf,sizeof(buf),0) < 0) //从服务器接受是否登陆成功信息
{
perror("recv");
return -1;
}
if(buf.type == 'T') //返回 T 登陆成功
{
printf("%s\n",buf.data);
printf("加载中..................\n");
sleep(2);
system("clear");
/*if(send(connfd,&buf,sizeof(buf),0) < 0) //发送登陆用户信息到服务器进行下一步单词查询
{
perror("send");
return -1;
}*/
desktop2(); //登陆后的界面
}
if(buf.type == 'F') //返回 F 登陆失败
{
printf("\033[01;31m%s\n\033[0m",buf.data);
}
return 0;
}
/**********查询单词**********/
int search_word(int connfd)
{
MSG buf;
MSG buf1;
char search_buf[50] = {0};
while(1)
{
bzero(&buf,sizeof(buf));
bzero(&buf1,sizeof(buf1));
bzero(search_buf,50);
printf("请输入查询的单词(\033[01;33mQ\033[0m 退出):");
scanf("%s",search_buf);
system("clear"); //清屏
buf.type = 'S';
strcpy(buf.name,search_buf);
//退出查询
if(strncmp(search_buf,"Q",1) == 0)
{
break;
}
if(send(connfd,&buf,sizeof(buf),0) < 0) //发送查询单词信息到服务器
{
perror("send");
return -1;
}
if(recv(connfd,&buf1,sizeof(buf1),0) < 0) //从服务器接受是否查询成功的信息
{
perror("recv");
return -1;
}
if(buf1.type == 'F')
{
printf("\033[01;31m抱歉!查询不到此单词,请重新输入想要查找的单词\033[0m\n");
continue;
}
else if(buf1.type == 'T')
{
printf("\033[01;32m查询结果:%s\033[0m\n",buf1.data);
}
else
{
printf("\033[01;31m服务器异常\033[0m\n");
break;
}
}
desktop2();//界面2
return 0;
}
/**********历史记录查询**********/
int do_history(int connfd)
{
char history_buf[10240] = {0}; //存放历史记录信息
MSG buf;
buf.type = 'H';
if(send(connfd,&buf,sizeof(buf),0) < 0)
{
perror("send");
return -1;
}
memset(&buf,sizeof(buf),0);
if(recv(connfd,history_buf,sizeof(history_buf),0) < 0)
{
perror("recv");
return -1;
}
if(strncmp(history_buf,"F",1) == 0)
{
printf("\033[01;32未查询到历史记录\033[0m\n");
}
else
{
printf("\033[01;32m历史记录查询成功!\033[0m\n");
printf("%s",history_buf);
desktop2();
}
return 0;
}
3.打印颜色效果设置
![](https://img-blog.csdnimg.cn/img_convert/310058d8a0332210d99bd34b88c5ddf4.png)