当前位置: 首页 > news >正文

8.21-8.22网络编程——词典

文章目录

  • 一、思维导图
  • 二、词典
    • 1、服务器
    • 2、客户端
    • 3、现象
  • 三、牛客网刷题

一、思维导图

在这里插入图片描述

二、词典

1、服务器

#include <myhead.h>#define SER_PORT  8888        //服务器端口号
#define SER_IP  "192.168.116.128"   //服务器IP地址 //账户密码结构
typedef struct acc_pass
{int num;char account[20];int password;
} acc_pass_t;//搜索查询结构
typedef struct search_query
{int num;char word[50];char account[20];
} search_query_t;//搜索历史结构
typedef struct search_history
{char client_ip[16];int client_port;char account[20];char search_word[50];char search_result[256];char search_time[20];
} search_history_t;/**************将文件中的词插入到表中********************/
int insert_word(sqlite3 *ppDb,char *buf1,char *buf2)
{char sql[256]="";snprintf(sql,sizeof(sql),"insert into WORD_TRANSLATE values(\"%s\",\"%s\");",buf1,buf2);char *errmsg=NULL;if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d插入失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************清空单词的数据表********************/
int empty_word(sqlite3 *ppDb)
{char sql[128]="delete from WORD_TRANSLATE;";char *errmsg=NULL;if(sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d清空失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************记录搜索历史********************/
int record_search_history(sqlite3 *ppDb,const char *client_ip,int client_port,const char *account,const char *word,const char *result)
{//获取当前时间time_t now =time(NULL);struct tm *t =localtime(&now);char timestamp[20];snprintf(timestamp,sizeof(timestamp),"%04d-%02d-%02d %02d:%02d:%02d",t->tm_year + 1900,t->tm_mon + 1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);char sql[512]="";snprintf(sql,sizeof(sql), "insert into SEARCH_HISTORY values(\"%s\",%d,\"%s\",\"%s\",\"%s\",\"%s\");",client_ip,client_port,account,word,result,timestamp);char *errmsg=NULL;if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d插入搜索历史失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************查询单词********************/
int query_word(sqlite3 *ppDb,const char *word,char *result,int result_size)
{char sql[256]="";snprintf(sql,sizeof(sql),"select translate from WORD_TRANSLATE where word=\"%s\";",word);char *errmsg=NULL;int found=0;int callback(void *data,int argc,char **argv,char **azColName) {if(argc>0&&argv[0]) {strncpy((char*)data,argv[0],result_size-1);found=1;}return 0;}if(sqlite3_exec(ppDb,sql,callback,result,&errmsg)!=SQLITE_OK){printf("%d查询失败%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}if(!found) {strncpy(result,"未找到该单词",result_size-1);}result[result_size-1]='\0';return 0;
}/***************查询搜索历史********************/
int query_search_history(sqlite3 *ppDb,const char *account,char *result,int result_size)
{char sql[256]="";snprintf(sql,sizeof(sql),"select search_time,search_word,search_result from SEARCH_HISTORY where account=\"%s\" order by search_time desc;", account);char *errmsg=NULL;result[0]='\0';int count=0;int callback(void *data,int argc,char **argv,char **azColName) {char *res=(char *)data;char line[512];snprintf(line,sizeof(line),"时间: %s\n单词: %s\n结果: %s\n\n",argv[0],argv[1],argv[2]);if(strlen(res)+strlen(line)<(size_t)(result_size-1)) {strcat(res,line);count++;}return 0;}if(sqlite3_exec(ppDb,sql,callback,result,&errmsg)!=SQLITE_OK){printf("%d查询历史记录失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}if(count==0) {strncpy(result,"无搜索历史记录",result_size-1);result[result_size-1]='\0';}return 0;
}/**************将账户密码插入到表中********************/
int insert_account(sqlite3 *ppDb,const char *account,int password)
{//检查账号是否已存在char check_sql[256]="";snprintf(check_sql,sizeof(check_sql),"select * from ACCOUNT_PASSWORD where account=\"%s\";",account);char *errmsg=NULL;int exists=0;int check_callback(void *data,int argc,char **argv,char **azColName) {*(int*)data=1;return 0;}if(sqlite3_exec(ppDb,check_sql,check_callback,&exists,&errmsg)!=SQLITE_OK){printf("%d查询账号失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}if(exists) {printf("账号已存在\n");return -1;}//插入新账号char sql[256] = "";snprintf(sql, sizeof(sql), "insert into ACCOUNT_PASSWORD values(\"%s\",%d,0);", account, password);if (sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入账号失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************清空账号密码的数据表********************/
int empty_account(sqlite3 *ppDb)
{char sql[128]="delete from ACCOUNT_PASSWORD;";char *errmsg=NULL;if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d清空账号表失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************登录账户********************/
int enter_account(sqlite3 *ppDb,const char *account,int password)
{char sql[256]="";snprintf(sql, sizeof(sql), "select * from ACCOUNT_PASSWORD where account=\"%s\" and password=%d and flag=0;",account, password);char *errmsg=NULL;int exists=0;int callback(void *data,int argc,char **argv,char **azColName) {*(int*)data=1;return 0;}if (sqlite3_exec(ppDb,sql,callback,&exists,&errmsg)!=SQLITE_OK){printf("%d查询账号失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}if (!exists) {return -1; //账号密码错误或已登录}//更新登录状态snprintf(sql,sizeof(sql),"update ACCOUNT_PASSWORD set flag=1 where account=\"%s\" and password=%d;",account,password);if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d更新登录状态失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************退出账户********************/
int break_account(sqlite3 *ppDb,const char *account,int password)
{char sql[256]="";snprintf(sql,sizeof(sql),"update ACCOUNT_PASSWORD set flag=0 where account=\"%s\" and password=%d;",account, password);char *errmsg=NULL;if(sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%d更新退出状态失败:%s\n",__LINE__,errmsg);sqlite3_free(errmsg);return -1;}return 0;
}/***************处理客户请求********************/
void handle_client(int new_fd,struct sockaddr_in cin,sqlite3 *ppDb)
{char client_ip[16] = {0};inet_ntop(AF_INET,&cin.sin_addr.s_addr,client_ip,sizeof(client_ip));int client_port=ntohs(cin.sin_port);printf("[%s:%d]连接成功,new_fd=%d\n",client_ip,client_port,new_fd);acc_pass_t p;search_query_t query;int flag;char result[4096]={0};char current_account[20]={0}; //记录当前登录账号while(1){memset(&p,0,sizeof(acc_pass_t));int res=recv(new_fd,&p,sizeof(acc_pass_t),0);if(res<=0){if(res==0){printf("客户端[%s:%d]已下线\n",client_ip,client_port);//如果已登录,更新状态if(strlen(current_account)>0){break_account(ppDb,current_account,p.password);}}else{perror("recv error");}break;}printf("收到客户端[%s:%d]请求: num=%d\n",client_ip,client_port,p.num);switch(p.num){case 1: //注册账号printf("注册账号: %s, %d\n",p.account,p.password);flag=insert_account(ppDb,p.account,p.password);break;case 2: //登录账户printf("登录账户:%s,%d\n",p.account,p.password);flag=enter_account(ppDb,p.account,p.password);if(flag==0){strcpy(current_account,p.account);}send(new_fd,&flag,sizeof(flag),0);break;case 3: //退出账户printf("退出账户:%s,%d\n",p.account,p.password);flag=break_account(ppDb,p.account,p.password);if(flag==0){memset(current_account,0,sizeof(current_account));}send(new_fd,&flag,sizeof(flag),0);break;case 4: //查询单词printf("查询单词请求\n");memset(&query,0,sizeof(query));if(recv(new_fd,&query,sizeof(query),0)<=0){perror("recv query error");flag=-1;break;}printf("用户[%s]查询单词:%s\n",query.account,query.word);memset(result,0,sizeof(result));if (query_word(ppDb,query.word,result,sizeof(result))==0){send(new_fd,result,strlen(result)+1,0);//记录搜索历史record_search_history(ppDb,client_ip,client_port, query.account, query.word, result);}else{send(new_fd,"查询失败",strlen("查询失败")+1,0);}break;case 5: //查询历史记录printf("查询历史记录请求,用户:%s\n",p.account);memset(result,0,sizeof(result));if(query_search_history(ppDb,p.account,result,sizeof(result))==0){send(new_fd,result,strlen(result)+1,0);}else{send(new_fd,"查询历史记录失败",strlen("查询历史记录失败")+1,0);}break;default:printf("未知请求:%d\n",p.num);break;}}close(new_fd);printf("[%s:%d]连接关闭,new_fd=%d\n",client_ip,client_port,new_fd);
}//处理僵尸进程
void handle_sigchild(int sig)
{while (waitpid(-1,NULL,WNOHANG)>0);
}/***************主函数********************/
int main(int argc, const char *argv[])
{//设置信号处理,回收僵尸进程signal(SIGCHLD,handle_sigchild);//打开词典文件int fd = open("./dict.txt",O_RDONLY);if(fd==-1){ERR_MSG("open dict.txt error");}//打开或创建数据库sqlite3 *ppDb=NULL;if (sqlite3_open("./dict.db",&ppDb)!=SQLITE_OK){printf("sqlite3_open error: %s\n",sqlite3_errmsg(ppDb));close(fd);return -1;}//创建单词表char *sql="create table if not exists WORD_TRANSLATE(word char primary key, translate char);";char *errmsg=NULL;if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("创建单词表失败:%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(ppDb);close(fd);return -1;}empty_word(ppDb); //清空单词表//创建账户表sql = "create table if not exists ACCOUNT_PASSWORD(account char primary key,password int,flag int);"; //flag: 0-未登录, 1-已登录if (sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("创建账户表失败:%s\n",errmsg);sqlite3_free(errmsg);sqlite3_close(ppDb);close(fd);return -1;}empty_account(ppDb); //清空账户表//创建搜索历史表sql = "create table if not exists SEARCH_HISTORY(client_ip char,client_port int,account char,search_word char,search_result char,search_time char);";if(sqlite3_exec(ppDb,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("创建历史表失败:%s\n",errmsg);sqlite3_free(errmsg);//不退出,继续执行}printf("初始化词典中\n");//从文件加载单词到数据库char buf1[128]={0}; //单词char buf2[512]={0}; //翻译char buf[1]={0};ssize_t nread;off_t file_size=lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);while (lseek(fd,0,SEEK_CUR)<file_size){memset(buf1,0,sizeof(buf1));memset(buf2,0,sizeof(buf2));//读取单词(到第一个空格)int i=0;while (i<sizeof(buf1)-1){nread=read(fd,buf,1);if(nread<=0)break;if(buf[0]==' '||buf[0]=='\t'||buf[0]=='\n'){break;}buf1[i++]=buf[0];}//跳过空格while(1){nread=read(fd,buf,1);if(nread<=0)break;if(buf[0]!=' '&&buf[0]!= '\t'){lseek(fd,-1,SEEK_CUR); //回退一个字符break;}}//读取翻译(到换行符)i=0;while(i<sizeof(buf2)-1){nread=read(fd,buf,1);if(nread<=0)break;if(buf[0]=='\n')break;buf2[i++]=buf[0];}if(strlen(buf1)>0){insert_word(ppDb,buf1,buf2);//printf("加载单词: %s -> %s\n", buf1, buf2);}}close(fd);printf("词典加载完成\n");//创建服务器套接字int sfd=socket(AF_INET,SOCK_STREAM,0);if(-1==sfd){ERR_MSG("socket error");}printf("socket创建成功,sfd = %d\n",sfd);//设置端口复用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){ERR_MSG("setsockopt error");}//绑定地址struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){ERR_MSG("bind error");}printf("bind成功\n");//监听if(listen(sfd, 128)==-1){ERR_MSG("listen error");}printf("listen成功,等待客户端连接...\n");struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);while(1){int new_fd = accept(sfd,(struct sockaddr*)&cin,&addrlen);if(-1==new_fd){perror("accept error");continue;}//创建子进程处理客户端pid_t pid=fork();if(pid==0){close(sfd); //子进程关闭监听套接字handle_client(new_fd,cin,ppDb);sqlite3_close(ppDb); //子进程关闭数据库exit(EXIT_SUCCESS);}else if(pid>0){close(new_fd); //父进程关闭通信套接字}else{close(new_fd);perror("fork error");}}//关闭资源(理论上不会执行到这里)sqlite3_close(ppDb);close(sfd);return 0;
}

2、客户端

#include <myhead.h>
#define SER_PORT  8888        //服务器端口号
#define SER_IP  "192.168.116.128"   //服务器IP地址 //账户密码结构
typedef struct acc_pass
{int num;char account[20];int password;
} acc_pass_t;//单词查询结构(与服务器保持一致)
typedef struct search_query
{int num;char word[50];char account[20];
} search_query_t;//注册账户
int do_register(int num,acc_pass_t *p,int cfd)
{printf("请输入账号:");scanf("%s",p->account);printf("请输入密码:");scanf("%d",&p->password);p->num=num;//发送注册信息if(send(cfd,p,sizeof(acc_pass_t),0)==-1){perror("send register error");return -1;}printf("注册信息发送成功\n");return 0;
}//登录账户
int do_login(int num,acc_pass_t *p,int cfd)
{printf("请输入账号:");scanf("%s",p->account);printf("请输入密码:");scanf("%d",&p->password);p->num=num;//发送登录信息if(send(cfd,p,sizeof(acc_pass_t),0)==-1){perror("send login error");return -1;}//接收登录结果int response;if(recv(cfd,&response,sizeof(response),0)==-1){perror("recv response error");return -1;}if (response==0){printf("登录成功\n");return 0;}else{printf("登录失败\n");return -1;}
}//退出账户
int do_logout(int num,acc_pass_t *p,int cfd)
{p->num=num;if(send(cfd,p,sizeof(acc_pass_t), 0)==-1){perror("send logout error");return -1;}int response;if (recv(cfd,&response,sizeof(response),0)==-1){perror("recv logout response error");return -1;}return response;
}//查询搜索历史
int do_search_history(int cfd,const char *account)
{acc_pass_t p;memset(&p,0,sizeof(acc_pass_t));p.num=5;strcpy(p.account,account);  //携带账号信息if(send(cfd,&p,sizeof(acc_pass_t),0)==-1){perror("send history request error");return -1;}//接收历史记录char history[4096]={0};int recv_len=recv(cfd,history,sizeof(history)-1,0);if(recv_len==-1){perror("recv history error");return -1;}printf("搜索历史记录:\n%s\n",history);return 0;
}//查询单词
int do_search_word(int cfd,const char *account)
{//发送查询类型标识acc_pass_t p;memset(&p,0,sizeof(acc_pass_t));p.num=4;strcpy(p.account,account);if (send(cfd,&p,sizeof(acc_pass_t),0)==-1){perror("send search type error");return -1;}//准备查询信息search_query_t query;memset(&query,0,sizeof(search_query_t));query.num=4;strcpy(query.account, account);printf("请输入要查询的单词:");scanf("%s",query.word);query.word[strcspn(query.word,"\n")]='\0';//发送查询请求if (send(cfd,&query,sizeof(query),0)==-1){perror("send word query error");return -1;}//接收查询结果char result[256]={0};int recv_len=recv(cfd,result,sizeof(result)-1,0);if(recv_len==-1){perror("recv word result error");return -1;}printf("查询结果: %s\n",result);return 0;
}int main(int argc, const char *argv[])
{//创建通信套接字int cfd=socket(AF_INET, SOCK_STREAM, 0);if(-1==cfd){perror("socket error");return -1;}printf("socket创建成功,cfd = %d\n",cfd);//连接服务器struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);if (connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("connect error");close(cfd);return -1;}printf("连接服务器成功\n");acc_pass_t *p=(acc_pass_t*)malloc(sizeof(acc_pass_t));if(p==NULL){perror("malloc error");close(cfd);return -1;}memset(p,0,sizeof(acc_pass_t));int num;int logged_in=0;//记录当前状态char current_account[20]={0};  //记录当前登录账号//数据收发循环while(1){if(!logged_in){printf("===== 请选择功能 =====\n");printf("1、注册账户\n");printf("2、登录账号\n");printf("3、退出程序\n");printf("======================\n");printf("选择功能:");scanf("%d",&num);switch(num){case 1:do_register(num,p,cfd);break;case 2:if(do_login(num,p,cfd) == 0){logged_in=1;strcpy(current_account,p->account);  //保存当前登录账号}break;case 3:printf("程序即将退出\n");free(p);close(cfd);return 0;default:printf("无效的选择,请重新输入\n");break;}}else{printf("===== 请选择功能 =====\n");printf("1、查找单词\n");printf("2、查找历史记录\n");printf("3、退出登录\n");printf("======================\n");printf("选择功能:");scanf("%d",&num);switch (num){case 1:do_search_word(cfd,current_account);break;case 2:do_search_history(cfd,current_account);break;case 3:do_logout(num,p,cfd);logged_in=0;memset(current_account,0,sizeof(current_account));printf("已退出登录\n");break;default:printf("无效的选择,请重新输入\n");break;}}}//关闭资源free(p);close(cfd);return 0;
}

3、现象

在这里插入图片描述

三、牛客网刷题

在这里插入图片描述

http://www.dtcms.com/a/343652.html

相关文章:

  • 集成电路学习:什么是Template Matching模版匹配
  • C++创建一个空类的时候,编译器会自动生成哪些函数了
  • 数据处理与统计分析 —— apply自定义函数
  • lesson44:Redis 数据库全解析:从数据类型到高级应用
  • 鸿蒙开发中的List组件详解
  • spring之自定义拦截器:HandlerInterceptor 控制请求生死权
  • Java微服务开发:从入门到精通
  • 证书只是手段:把学习变成可复用能力的路线图
  • FPGA 在情绪识别领域的护理应用(三)
  • gRPC 与 HTTP 性能对比分析
  • C++浅拷贝和深拷贝区别
  • 【华为OD-C卷-019 对称字符串 100分(python、java、c++、js、c)】
  • 【Transient-Free 3DGS】delayed densification + coarse to fine增加GS的鲁棒性
  • 【GaussDB】使用gdb定位GaussDB编译package报错
  • 图像中物体计数:基于YOLOv5的目标检测与分割技术
  • 智能编程中的智能体与 AI 应用:概念、架构与实践场景
  • Effective C++ 条款54:熟悉标准库
  • typescript常用命令选项
  • Function Call与MCP:大模型能力扩展的两条路径对比
  • CF每日4题(1500-1700)
  • 谈谈架构的内容
  • 前端别名与环境变量使用
  • AI 赋能教育变革:机遇、实践与展望
  • 基于随机森林的红酒分类与特征重要性分析
  • MySQL高可用之MHA实战
  • 【高等数学】第九章 多元函数微分法及其应用——第九节 二元函数的泰勒公式
  • 北京JAVA基础面试30天打卡14
  • 【51单片机学习】AT24C02(I2C)、DS18B20(单总线)、LCD1602(液晶显示屏)
  • AI 在医疗领域的应用与挑战
  • 带宽评估(三)lossbase_v2