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

8.21网络编程——词典(未完成,有问题)

文章目录

  • 一、词典
    • 1、服务器
    • 2、客户端

一、词典

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;
//搜索查询结构
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)
{//准备sql语句char sql[256] = "";          //存储sql语句的数组sprintf(sql, "insert into WORD_TRANSLATE values(\"%s\",\"%s\");",buf1,buf2);char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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)
{//准备sql语句char sql[128] = "";          //存储sql语句的数组sprintf(sql, "delete from WORD_TRANSLATE;");char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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, char *client_ip, int client_port, char *account, char *word, 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);//准备sql语句char sql[512] = "";          //存储sql语句的数组sprintf(sql, "insert into SEARCH_HISTORY values(\"%s\", %d, \"%s\", \"%s\", \"%s\", \"%s\");",\client_ip,client_port,account, word, result, timestamp);char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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, char *word, char *result, int result_size)
{//准备sql语句char sql[256] = "";          //存储sql语句的数组sprintf(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(result, argv[0], result_size - 1);result[result_size - 1] = '\0';found = 1;}return 0;}//调用执行sql语句的函数if(sqlite3_exec(ppDb, sql, callback, NULL, &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 insert_account(sqlite3 *ppDb,char* account,int password)
{int flag=0;//准备sql语句char sql[256] = "";          //存储sql语句的数组sprintf(sql,"insert into ACCOUNT_PASSWORD values(\"%s\",%d,%d);",account,password,flag);char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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)
{//准备sql语句char sql[128] = "";          //存储sql语句的数组sprintf(sql, "delete from ACCOUNT_PASSWORD;");char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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,char* account,int password)
{//准备sql语句char sql1[256] = "";          //存储sql语句的数组sprintf(sql1,"select * from ACCOUNT_PASSWORD where account==\"%s\" and password==%d and flag==0;",account,password);char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d查询失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}//准备sql语句char sql[256] = "";          //存储sql语句的数组sprintf(sql,"update ACCOUNT_PASSWORD set flag=1 where account==\"%s\" and password==%d;",account,password);//char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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,char* account,int password)
{//准备sql语句char sql1[256] = "";          //存储sql语句的数组sprintf(sql1,"select * from ACCOUNT_PASSWORD where account==\"%s\" and password==%d and flag==1;",account,password);char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d查询失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}//准备sql语句char sql[256] = "";          //存储sql语句的数组sprintf(sql,"update ACCOUNT_PASSWORD set flag=0 where account==\"%s\" and password==%d;",account,password);//char *errmsg = NULL;            //接收错误信息//调用执行sql语句的函数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)
{printf("[%s:%d]发来连接,new_fd = %d\n", inet_ntoa(cin.sin_addr),ntohs(cin.sin_port) ,new_fd);acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass));search_query_t query;//用来查询单词的结构体int flag;char result[4096];char current_account[20]={};//记录当前登录的账号while(1){memset(p,0,sizeof(struct acc_pass));int res=recv(new_fd,p,sizeof(struct acc_pass),0);if(res<=0){if(res==0){printf("客户端[%s:%d]已下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));//如果登录过则退出if(strlen(current_account)>0){break_account(ppDb,current_account,p->password);}}else{perror("recv error");}break;}printf("收到客户端[%s:%d]请求: num=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_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");// 检查是否已登录if (strlen(current_account) == 0) {strcpy(result, "请先登录");send(new_fd, result, strlen(result) + 1, 0);break;}// 接收单词memset(&query, 0, sizeof(query));recv(new_fd, &query, sizeof(query), 0);printf("查询单词: %s\n", 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);printf("查询结果: %s -> %s\n", query.word, result);// 记录搜索历史record_search_history(ppDb,p->account,p->password , current_account, query.word, result);}else{send(new_fd, "查询失败", 9, 0);}break;default:printf("未知请求:%d\n",p->num);break;}}free(p);close(new_fd);printf("[%s:%d]链接处理结束,new_fd = %d\n", inet_ntoa(cin.sin_addr),ntohs(cin.sin_port) ,new_fd);}/***************主函数********************/
int main(int argc, const char *argv[])
{//将文件导入到库中//打开四级词汇文件int fd=open("./dict.txt",O_RDONLY);if(fd==-1){ERR_MSG("open error");}//创建库sqlite3 *ppDb=NULL;if(sqlite3_open("./dict.db",&ppDb)!=SQLITE_OK){printf("sqlite3_open error errcode=%d, errmsg=%s\n",sqlite3_errcode(ppDb), sqlite3_errmsg(ppDb));return -1;}//创建数据表//准备sql语句char *sql = "create table if not exists WORD_TRANSLATE(word char,translate char);";char *errmsg = NULL;      //用于接收错误信息的指针//调用执行sql语句的函数if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("数据表创建失败:%s\n", errmsg);sqlite3_free(errmsg);              //释放错误信息的空间return -1;}//清空数据表empty_word(ppDb);	//创建账户密码的数据表//准备sql语句char *sql1 = "create table if not exists ACCOUNT_PASSWORD(account char,password int,flag int);";//char *errmsg = NULL;      //用于接收错误信息的指针//调用执行sql语句的函数if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("数据表创建失败:%s\n", errmsg);sqlite3_free(errmsg);              //释放错误信息的空间return -1;}//清空数据表empty_account(ppDb);//从文件中读取信息char buf1[128];//记录单词名字char buf2[128];//记录单词翻译char buf[1]={};size_t set=0;off_t set1,set2;set1=lseek(fd,0,SEEK_END);//设置退出条件lseek(fd,0,SEEK_SET);while(1){//sleep(1);memset(buf1,0,sizeof(buf1));memset(buf2,0,sizeof(buf2));memset(buf,0,sizeof(buf));for(int i=0;i<128&&buf[0]!=' '&&buf[0]!='\n';i++){set=read(fd,buf,sizeof(buf));buf1[i]=buf[0];if(set==0){break;}}buf1[strcspn(buf1," ")]='\0';while(buf[0]==' ')//吸收两个字符之间的空格{set=read(fd,buf,sizeof(buf));}lseek(fd,-1,SEEK_CUR);printf("work=%s",buf1);for(int i=0;i<128&&buf[0]!='\n';i++){set=read(fd,buf,sizeof(buf));buf2[i]=buf[0];set2=lseek(fd,0,SEEK_CUR);//确定当前光标所在位置if(set==0){break;}}buf2[strcspn(buf2,"\n")]='\0';printf("buf2=%s\n",buf2);//将读取到的值写入词典数据表中insert_word(ppDb,buf1,buf2);if(set1==set2){break;}}close(fd);//关闭文件//创建一个用于连接的套接字文件描述符int sfd  = socket(AF_INET, SOCK_STREAM, 0);if(-1 == sfd){perror("socket  error");return -1;}printf("socket 成功 sfd = %d\n", sfd);//设置套接字属性:允许端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");//给套接字绑定ip地址和端口号//封装地址信息结构体变量struct sockaddr_in sin;        //地址信息结构体变量sin.sin_family = AF_INET;      //通信域地址族sin.sin_port = htons(SER_PORT);   //端口号网络字节序sin.sin_addr.s_addr = inet_addr(SER_IP);  //ip地址网络字节序//绑定操作if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1){perror("bind  error");return -1;}printf("bind success\n");//将套接字启动监听if(listen(sfd, 128) == -1){perror("listen  error");return -1;}printf("listen success\n");//阻塞等等客户端的连接,如果有新客户端连接,//则创建一个用于通信的套接字struct sockaddr_in cin;            //用于接受客户端套接字信息socklen_t addrlen = sizeof(cin);   //用于接受客户端套接字的长度acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass));//存放接受消息的容器while(1){int new_fd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(-1 == new_fd){perror("accept error");continue;}printf("[%s:%d]发来连接,new_fd = %d\n", inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port) ,new_fd);//为每个客户端创建一个子进程pid_t pid=fork();if(pid==0){//子进程close(sfd);//关闭监听套接字//处理客户端请求handle_client(new_fd,cin,ppDb);exit(EXIT_SUCCESS);}else if(pid>0){//父进程close(new_fd);//关闭已经连接的套接字}else{close(new_fd);ERR_MSG("fork error");}}sqlite3_close(ppDb);//关闭数据库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;
//单词查询结构
typedef struct word_query
{int num;char word[50];
} word_query_t;
int do_add(int num,acc_pass p,int cfd)
{printf("输入账号:");scanf("%s",p->account);printf("输入密码:");scanf("%d",&p->password);p->num=num;//将数据发送给服务器send(cfd, p, sizeof(struct acc_pass), 0);printf("发送成功\n");
}
int do_register(int num,acc_pass p,int cfd)
{printf("输入账号:");scanf("%s",p->account);printf("输入密码:");scanf("%d",&p->password);p->num=num;	send(cfd, p, sizeof(struct acc_pass), 0);printf("发送成功\n");}
int do_search_word(int cfd)
{word_query_t query;query.num = 4; // 查询单词的请求类型printf("请输入要查询的单词:");scanf("%s", query.word);// 发送查询请求send(cfd, &query, sizeof(query), 0);// 接收查询结果char result[256];recv(cfd, result, sizeof(result), 0);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 success   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);    //服务器ip地址//连接服务器if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect  error");return -1;}printf("连接成功\n");acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass));      //用于发送数据的容器int num;//数据收发while(1){printf("1、注册账户\n");printf("2、登录账号\n");printf("3、退出账户\n");printf("选择功能:");scanf("%d",&num);switch(num){case 1:do_add(num,p,cfd);break;case 2:do_register(num,p,cfd);//if(){while(1){printf("1、查找单词\n");printf("2、查找历史记录\n");printf("3、返回上一级\n");printf("选择功能:");scanf("%d",&num);switch(num){case 1://查找单词do_search_word(cfd);break;case 2://查找历史记录break;case 3://返回上一级break;}if(num==3){break;}}}break;case 3://do_break;break;}}//5关闭套接字close(cfd);return 0;
}
http://www.dtcms.com/a/342946.html

相关文章:

  • kotlin协程笔记-朱凯
  • C# 基本数据类型
  • 生信分析自学攻略 | R语言数据筛选和修改
  • 前端:文件直接在浏览器里下载
  • VMware ESXi 服务器暴露高危漏洞,中国1700余台面临勒索软件威胁
  • UE 虚幻引擎, unreal engine(1)概略介绍,安装本引擎,创建账户,打开 UE,创建项目,项目导入内容,尝试运行的添加第一人称游戏,
  • Vibe Coding v.s Prompt Engineering
  • 【Docker】在Ubuntu22.04上安装Docker
  • 漫谈《数字图像处理》之平滑
  • 智能编码工具:GitHub Copilot 的深度应用与集成
  • 用OpencvSharp编写视频录制工具
  • HTTP/2 性能提升的核心原因
  • Vue2 ElementUI Upload组件http-request用法
  • (二十一)深入了解AVFoundation-编辑:导出视频与格式转换的全流程
  • 全文 part1 - DGEMM Using Tensor Cores, and Its Accurate and Reproducible Versions
  • DeepSeek-V3.1 发布,迈向 Agent 时代的第一步
  • 0821 sqlite3_get_table函数(数据库函数的补充)
  • Nacos-9--认识Nacos中的Distro协议(Nacos高可用的实现原理)
  • visual studio编译的软件查找所依赖的运行库方法
  • 基于单片机智能路灯控制
  • 学习嵌入式第三十四天
  • 杂记 07
  • BGP高级特性
  • AI论文速读 | 多模态能否助力时间序列预测?时序预测中融合文本的边界与条件
  • Oracle CLOB类型转换
  • 数据分析三剑客
  • 如何解读京东按图搜索(拍立淘)API(jd.item_search_img)的返回值
  • AI大模型支持下的:CMIP6数据分析与可视化、降尺度技术与气候变化的区域影响、极端气候分析
  • JVM-(7)堆内存逻辑分区
  • 3个脱节,5大特征,1套方法:破解AI落地难题