电子词典dictionary
一、项目要求:
1.登录注册功能,不能重复登录,重复注册。用户信息也存储在数据库中。
2.单词查询功能
3.历史记录功能,存储单词,意思,以及查询时间,存储在数据库
4.基于TCP,支持多客户端连接
5.采用数据库保存用户信息与历史记录
6.将dict.txt的数据导入到数据库中保存。
7.返回上级、按下ctrl+c退出客户端后,该用户退出登录
二、格式要求:
1.main函数只跑逻辑,不允许跑功能代码
2.功能代码封装成函数
三、项目功能:
1.注册
2.登录
3.查询单词
4.查看历史记录
5.退出登录
四、框架设计:
4.1服务器设计

4.2客户端设计
五、功能说明:
5.1用户注册
输入用户名和密码,插入用户表中,用户名不能和已有用户名字冲突,否则失败。
5.2用户登录
输入用户名和密码,通过遍历表中数据,核对数据信息,成功,转到第二个操作界面。
5.3查询单词
输入单词,在词典文件中查找,存在得到单词解释,并且将查询记录保存到记录表中。
5.4查询历史记录
遍历记录表中数据,将用户查询的时间和单词打印到终端上。
5.5多进程实现TCP并发
六、具体代码:
head.h:
#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <sqlite3.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <time.h>#define PORT 8808
#define IP "127.0.0.1"
#define ERR_MSG(msg) { fprintf(stderr,"__%d__",__LINE__); perror(msg); }int put_dict(sqlite3 *db);
void handler(int sig);
int do_register(sqlite3 *db,char *buf);
void do_register_cli(char *buf);
int Register(sqlite3 *db,char *buf);
void do_login(char *buf);
int Login(sqlite3 *db,char *buf);
int do_select_user(sqlite3 *db,char *name);
int do_insert(sqlite3 *db,char *words,char *mean,char *save_buf);
int Search(sqlite3 *db,char *buf,char *save_buf);
int Search_res(sqlite3 *db,char *buf,char *save_buf);
int deal_cli_msg(int newfd,struct sockaddr_in cin,sqlite3 *db);#endif
dictionary.c(功能函数):
#include "head.h"//导入词典
int put_dict(sqlite3 *db)
{//创建并打开一个数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){printf("sqlite3_open:%s %d __%d__\n",\sqlite3_errmsg(db),sqlite3_errcode(db),__LINE__);return -1;}//创建一个表格 create table stu (id int,name char,score float);//数据库中sql语句怎么写,这里就怎么写char sql[128] = "create table dict (word char,mean char);";char* errmsg = NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_open:%s %d __%d__\n",\errmsg,sqlite3_errcode(db),__LINE__);return -1;}//打开文件FILE* fp = fopen("./dict.txt","r");if(NULL == fp){perror("fopen");return -1;}//循环读取文件中的数据,一行一行的读取char buf[256] = "";char word[32] = "";char mean[200] = "";int count = 1;int i =0;char* ptr = NULL;while(1){if(fgets(buf,sizeof(buf),fp) == NULL)break;buf[strlen(buf)-1] = 0;//分离单词和意思bzero(word,sizeof(word));bzero(mean,sizeof(mean));//获取" "子串在buf中的地址ptr = strstr(buf," ");if(NULL == ptr){printf("没有找到对应子串\n");break;}strncpy(word,buf,ptr-buf); //" "子串前面是单词strcpy(mean,ptr+3); //" "子串后面是意思//插入到数据库中sprintf(sql,"insert into dict values(\"%s\",\"%s\");",word,mean);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){printf("sqlite3_exec failed:%s __%d__\n",errmsg,__LINE__);return -1;}}printf("数据库建立成功\n");//关闭文件fclose(fp);//关闭数据库if(sqlite3_close(db) != SQLITE_OK){fprintf(stderr,"sqlite3_close:%s %d __%d__\n",\sqlite3_errmsg(db),sqlite3_errcode(db),__LINE__);return -1;}return 0;
}//捕获信号
void handler(int sig)
{while(waitpid(-1, NULL, WNOHANG) > 0);
}//实现注册功能
int do_register(sqlite3 *db,char *buf)
{//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}//创建一个表char sql[128] = "create table if not exists user (name char,passwd char);";char *errmsg = NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}char *name = buf+2;char *passwd = buf+2+strlen(buf+2)+1;if(do_select_user(db,name) == 1){if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 1;}sprintf(sql,"insert into user values ('%s','%s');",name,passwd);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}printf("register success...\n");//关闭数据库,释放对应的内存空间if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 0;
}//客户端注册函数
void do_register_cli(char *buf)
{char name[32] = "";char passwd[32] = "";printf("请输入您的用户名>>>");scanf("%s",name);getchar();printf("请输入您的密码>>>");scanf("%s",passwd);getchar();sprintf(buf,"%s%c%s%c%s","1",0,name,0,passwd);
}//实现注册功能
int Register(sqlite3 *db,char *buf)
{//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}//创建一个表char sql[128] = "create table if not exists user (name char,passwd char);";char *errmsg = NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}char *name = buf+2;char *passwd = buf+2+strlen(buf+2)+1;if(do_select_user(db,name) == 1){if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 1;}sprintf(sql,"insert into user values ('%s','%s');",name,passwd);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}printf("register success...\n");//关闭数据库,释放对应的内存空间if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 0;
}//登录函数
void do_login(char *buf)
{char name[32] = "";char passwd[32] = "";printf("请输入用户名>>>");scanf("%s",name);getchar();printf("请输入密码>>>");scanf("%s",passwd);getchar();sprintf(buf,"%s%c%s%c%s","2",0,name,0,passwd);
}//实现登录功能
int Login(sqlite3 *db,char *buf)
{//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}char sql[128] = "create table if not exists user (name char,passwd char);";char *errmsg = NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}strcpy(sql,"select * from user;");char **pres = NULL;int row,column;if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}char *name = buf+2;char *passwd = buf+2+strlen(buf+2)+1;for(int i=2;i<(row+1)*column;i++){if(strcmp(pres[i],name) == 0 && strcmp(pres[i+1],passwd) == 0){printf("login success...\n");if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 2;}}//关闭数据库,释放对应的内存空间if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 3;
}//查找用户名是否存在
int do_select_user(sqlite3 *db,char *name)
{char sql[128] = "select name from user;";char **pres = NULL;int row,column;char *errmsg = NULL;if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}for(int i=1;i<(row+1)*column;i++){if(strcmp(pres[i],name) == 0){fprintf(stderr,"sqlite3_exec: name already existss\n");return 1;}}return 0;
}//实现查询功能函数
int do_insert(sqlite3 *db,char *words,char *mean,char *save_buf)
{//获取当前时间戳time_t t;struct tm *info=NULL;char mytime[128] = "";t = time(NULL);info = localtime(&t);sprintf(mytime,"%d-%02d-%02d %02d:%02d:%02d",info->tm_year+1900,info->tm_mon+1,info->tm_mday,info->tm_hour,info->tm_min,info->tm_sec);//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}//创建一个表char sql[128] = "create table if not exists history (name char,word char,mean char,time char);";char *errmsg = NULL;char *name = save_buf;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}//插入查询记录sprintf(sql,"insert into history values (\"%s\",\"%s\", \"%s\",\"%s\");",name,words, mean,mytime);if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("sqlite3_exec failed:%s __%d__\n", errmsg, __LINE__);return -1;}printf("do_insert success...\n");
}//查询单词
int do_search(sqlite3 *db,char *buf,char *save_buf)
{//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}char sql[128] = "select * from dict;";char **pres = NULL;int row,column;char *errmsg = NULL;if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_get_table: %s __%d__\n",errmsg,__LINE__);return -1;}char *words = buf+2;for(int i=0;i<(row+1)*column;i++){if(strcmp(pres[i],words) == 0){//若查询成功,则将该单词插入记录do_insert(db,words,pres[i+1],save_buf);bzero(buf, sizeof(buf));sprintf(buf,"\t%s\t\t%s\t",pres[i],pres[i+1]);if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 4;}}//关闭数据库,释放对应的内存空间if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}return 5;
}//查询记录函数
int do_search_res(sqlite3 *db,char *buf,char *save_buf)
{//打开数据库if(sqlite3_open("./dict.db",&db) != SQLITE_OK){fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);return -1;}char sql[128] = "create table if not exists history (name char,word char,mean char,time char);";char *errmsg = NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);return -1;}char msg[128] = "";strcpy(sql,"select * from history;");char **pres = NULL;int row,column;if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK){fprintf(stderr,"sqlite3_get_table: %s __%d__\n",errmsg,__LINE__);return -1;}bzero(buf,sizeof(buf));for(int i=4;i<(row+1)*column;i++){if(i%4==0 && strcmp(save_buf,pres[i]) == 0){sprintf(msg,"%s\t%s\t%s\t%s\n",pres[i],pres[i+1],pres[i+2],pres[i+3]);strcat(buf,msg);}}if(strlen(buf)!=0)*(buf+strlen(buf)-1) = 0;//关闭数据库,释放对应的内存空间if(sqlite3_close(db) != SQLITE_OK){printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);return -1;}if(strlen(buf) == 0)return 7;return 6;
}
//服务器子进程处理客户端信息
int deal_cli_msg(int newfd,struct sockaddr_in cin,sqlite3 *db)
{int flag = 0;char buf[128] = "";char save_buf[128] = "";ssize_t res = 0;int f_res = -1;while(1){bzero(buf, sizeof(buf));//接收数据res = recv(newfd, buf, sizeof(buf), 0);if(res < 0){ERR_MSG("recv");return -1;}else if(0 == res){printf("[%s : %d] client offline\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));break;}//调用功能函数if(strcmp(buf,"1") == 0)f_res = Register(db,buf); //注册else if(strcmp(buf,"2") == 0){f_res = Login(db,buf); //登录strcpy(save_buf,buf+2); //将用户名另存}else if(strcmp(buf,"3") == 0){f_res = do_search(db,buf,save_buf); //查询单词}else if(strcmp(buf,"4") == 0)f_res = do_search_res(db,buf,save_buf); //查询记录//发送数据if(0 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[注册成功!]");}else if(1 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[对不起,注册失败,该用户名已存在!]");}else if(2 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[登录成功!]");}else if(3 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[对不起,登录失败,该用户名/密码不存在!]");}else if(5 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[对不起,无法查找找到该单词!]");}else if(7 == f_res){bzero(buf, sizeof(buf));strcpy(buf,"[对不起,该用户没有历史记录!]");}if(send(newfd, buf, sizeof(buf), 0) < 0){ERR_MSG("send");return -1;}}close(newfd);return 0;
}
服务器(Ser.c):
#include "head.h"
int main(int argc, const char *argv[])
{sqlite3 *db = NULL;if(signal(17, handler) == SIG_ERR){ERR_MSG("signal");return -1;}//导入词典 put_dict(db);//创建流式套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd < 0){ERR_MSG("socket");return -1;}//设置允许端口号复用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { perror("setsockopt");return -1;}//绑定服务器IP和端口号struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}//将套接字设置为被动监听状态if(listen(sfd,10) < 0){ERR_MSG("listen");return -1;}int newfd = -1;struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);//从已完成连接的队列中获取一个客户端信息,生成一个新的文件描述符while(1){newfd = accept(sfd,(struct sockaddr *)&cin,&addrlen);if(newfd < 0){ERR_MSG("accept");return -1;}printf("[%s : %d] connect success...\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));if(0 == fork()){close(sfd);deal_cli_msg(newfd,cin,db);exit(0);}close(newfd);}close(sfd);return 0;
}
客户端(Cli.c):
#include "head.h"int main(int argc, const char *argv[])
{sqlite3 *db =NULL;//创建流式套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd < 0){ERR_MSG("socket");return -1;}printf("cfd = %d\n", cfd);//绑定客户端的的IP和端口--->非必须绑定//若不绑定,则操作系统会给客户端绑定上客户端所在的主机IP,以及随机端口(49152~65535)//填充服务器的地址信息结构体,真实的地址信息结构体根据地址族指定//AF_INET: man 7 ip //要连接哪个服务器,就填对应服务器的IP和端口struct sockaddr_in sin;sin.sin_family = AF_INET; //必须填AF_INETsin.sin_port = htons(PORT); //端口号: 填服务器绑定端口号sin.sin_addr.s_addr = inet_addr(IP); //IP地址:服务器绑定的IP地址//连接服务器if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("connect");return -1;}printf("connect success\n");ssize_t res = 0;char buf[128] = "";char buf1[128] ="";char save_buf[128] ="";char choose = 0;while(1){system("clear");printf("-----------------------\n");printf("---------1.注册--------\n");printf("---------2.登录--------\n");printf("---------3.退出--------\n");printf("-----------------------\n");printf("请输入您需要执行的操作>>>");choose = getchar();while(getchar() != 10);switch(choose){case '1'://注册函数do_register_cli(buf);break;case '2'://登录函数do_login(buf);break;case '3'://退出函数goto END;default:printf("对不起,您的输入有误,请重新输入\n");}//发送数据if(send(cfd,buf,sizeof(buf),0) < 0){perror("send");return -1;}//接受数据bzero(buf,sizeof(buf));res = recv(cfd,buf,sizeof(buf),0);if(res < 0){perror("recv");return -1;}else if(0 == res){printf("[%s : %d] server offline\n",IP,PORT);break;}printf("%s\n",buf);strcpy(save_buf,buf);while(strcmp(save_buf,"[登录成功!]") == 0){system("clear");printf("--------------------------\n");printf("-------1.查找单词---------\n");printf("-------2.查找历史记录-----\n");printf("-------3.退出登录---------\n");printf("--------------------------\n");printf("请输入您要执行的操作>>>");choose = getchar();while(getchar() != 10);// bzero(buf,sizeof(buf));// fgets(buf,sizeof(buf),stdin);// buf[strlen(buf)-1] = 0;char words[20] = "";switch(choose){case '1':{while(1){bzero(buf,sizeof(buf));printf("请输入您要查找的单词(输入 \"#\" 结束)>>>");scanf("%s",words);getchar();if(strcmp(words,"#") == 0)break;sprintf(buf,"%s%c%s%c","3",0,words,0);//发送数据if(send(cfd,buf,sizeof(buf),0) < 0){perror("send");return -1;}//接收查询单词结果bzero(buf,sizeof(buf));res = recv(cfd,buf,sizeof(buf),0);if(res < 0){perror("recv");return -1;}else if(0 == res){printf("[%s : %d] server offline\n",IP,PORT);// break;goto END;}printf("%s\n",buf);}}break;case '2'://登录函数{sprintf(buf,"%s%c","4",0);//发送数据if(send(cfd,buf,sizeof(buf),0) < 0){perror("send");return -1;}//接受查询单词结果bzero(buf,sizeof(buf));res = recv(cfd,buf,sizeof(buf),0);if(res < 0){perror("recv");return -1;}else if(0 == res){printf("[%s : %d] server offline\n",IP,PORT);goto END;// break;}printf("%s\n",buf);}break;case '3':goto END1;default:printf("对不起,您的输入有误,请重新输入\n");}printf("输入任意字符清屏>>>");while(getchar() != 10);}
END1:printf("输入任意字符清屏>>>");while(getchar() != 10);}
END://关闭所有文件描述符close(cfd);return 0;
}
相关文章:
电子词典dictionary
一、项目要求: 1.登录注册功能,不能重复登录,重复注册。用户信息也存储在数据库中。 2.单词查询功能 3.历史记录功能,存储单词,意思,以及查询时间,存储在数据库 4.基于TCP,支持多客户…...
【python爬虫】10.指挥浏览器自动工作(selenium)
文章目录 前言selenium是什么怎么用设置浏览器引擎获取数据解析与提取数据自动操作浏览器 实操运用确认目标分析过程代码实现 本关总结 前言 上一关,我们认识了cookies和session。 分别学习了它们的用法,以及区别。 还做了一个项目:带着小…...
QT文件对话框,将标签内容保存至指定文件
一、主要步骤 首先,通过getSaveFileName过去想要保存的文件路径及文件名,其次,通过QFile类实例化一个文件对象,再读取文本框中的内容,最后将读取到的内容写入到文件中,最后关闭文件。 1.txt即为完成上述操作…...
C#,《小白学程序》第十一课:阶乘(Factorial)的计算方法与代码
1 文本格式 /// <summary> /// 阶乘的非递归算法 /// </summary> /// <param name"a"></param> /// <returns></returns> private int Factorial_Original(int a) { int r 1; for (int i a; i > 1; i--) { …...
MySQL 数据库常用命令大全(完整版)
文章目录 1. MySQL命令2. MySQL基础命令3. MySQL命令简介4. MySQL常用命令4.1 MySQL准备篇4.1.1 启动和停止MySQL服务4.1.2 修改MySQL账户密码4.1.3 MySQL的登陆和退出4.1.4 查看MySQL版本 4.2 DDL篇(数据定义)4.2.1 查询数据库4.2.2 创建数据库4.2.3 使…...
【数学】【书籍阅读笔记】【概率论】应用随机过程概率论模型导论 by Sheldon M.Ross 第一章 概率论引总结与习题题解 【更新中】
文章目录 前言1 第一章 概率论引论 总结1.1 样本空间与事件1.2 定义在事件上的概率1.3 条件概率1.4 独立事件 2 一些有用的重要结论/公式/例题3 重要例题例 1.11 3 习题题解题1题2 4 习题总结 前言 1 第一章 概率论引论 总结 第一章从事件的角度引出样本空间、事件、概率的基本…...
posexplode函数实战总结
目录 1、建表和准备数据 2、炸裂实践 3、错误炸裂方式 4、当字段类型为string,需要split一下 对单列array类型的字段进行炸裂时,可以使用lateral view explode。 对多列array类型的字段进行炸裂时,可以使用lateral view posexplode。 1…...
QTday3(对话框、发布软件、事件处理核心机制)
一、Xmind整理: 二、上课笔记整理: 1.消息对话框(QMessageBox) ①基于属性版本的API QMessageBox::QMessageBox( //有参构造函数名QMessageBox::Icon icon, //图标const Q…...
el-date-picker限制选择的时间范围
<el-date-pickersize"mini"v-model"dateTime"value-format"yyyy-MM-dd HH:mm:ss"type"datetimerange"range-separator"~"start-placeholder"开始日期"end-placeholder"结束日期":picker-options&quo…...
Scala中的Actor模型
Scala中的Actor模型 概念 Actor Model是用来编写并行计算或分布式系统的高层次抽象(类似java中的Thread)让程序员不必为多线程模式下共享锁而烦恼。Actors将状态和行为封装在一个轻量的进程/线程中,但是不和其他Actors分享状态,…...
Java使用pdfbox将pdf转图片
前言 目前比较主流的两种转pdf的方式,就是pdfbox和icepdf,两种我都尝试了下,icepdf解析出来有时候会出现中文显示不出来,网上的解决方式又特别麻烦,不是安装字体,就是重写底层类,所以我选择了p…...
大规模场景下对Istio的性能优化
简介 当前istio下发xDS使用的是全量下发策略,也就是网格里的所有sidecar(envoy),内存里都会有整个网格内所有的服务发现数据。这样的结果是,每个sidecar内存都会随着网格规模增长而增长。 Aeraki-mesh aeraki-mesh项目下有一个子项目专门用来…...
数字化新零售平台系统提供商,门店商品信息智慧管理-亿发进销存
传统的批发零售业务模式正面临着市场需求变化的冲击。用户日益注重个性化、便捷性和体验感,新兴的新零售模式迅速崛起,改变了传统的零售格局。如何在保持传统业务的基础上,变革发展,成为了业界亟需解决的问题。 在这一背景下&…...
postgresql-窗口函数
postgresql-窗口函数 简介窗口函数的定义分区选项(PARTITION BY)排序选项(ORDER BY)窗口选项(frame_clause) 聚合窗口函数排名窗口函数演示了 CUME_DIST 和 NTILE 函数 取值窗口函数 简介 常见的聚合函数&…...
Revit SDK 介绍:CreateAirHandler 创建户式风管机
前言 这个例子介绍如何通过 API 创建一个户式风管机族的内容,包含几何和接头。 内容 效果 核心逻辑 必须打开机械设备的族模板创建几何实体来表示风管机创建风机的接头 创建几何实体来表示风管机 例子中创建了多个拉伸,下面仅截取一段代码ÿ…...
微信小程序云开发-云函数发起https请求简易封装函数
一、前言 在日常的开发中,经常会遇到需要请求第三方API的情况,例如请求实名认证接口、IP转换地址接口等等。这些请求放在小程序前端的话,就需要把密钥放在客户端,在安全性上没这么高。 因此,一般是放在云函数端去访问…...
深入探索PHP编程:连接数据库的完整指南
深入探索PHP编程:连接数据库的完整指南 在现代Web开发中,与数据库进行交互是不可或缺的一部分。PHP作为一种强大的服务器端编程语言,提供了丰富的工具来连接和操作各种数据库系统。本篇教程将带您了解如何在PHP中连接数据库,执行…...
【Centos8配置节点免密登陆】
登录Centos8 配置免密登录 为什么需要配置免密登录,玩大数据,玩集群的朋友们,都需要使用RPC通讯,完成集群命令同步,数据操作通讯。要实现RPC通讯,就需要配置节点之间的免密登录。 # 配置登录秘钥 ssh-key…...
不可变集合、Lambda表达式、Stream流
不可变集合、Lambda表达式、Stream流 创建不可变集合 不能被修改的集合 应用场景 如果某个数据不能被修改,把它防御性的拷贝到不可变集合中是个很好的实践。 当集合对象被不可信的库调用时,不可变形式是安全的。 创建不可变集合 在List、Set、Map接口中…...
Three.js GLTF模型加载
在Three.js中,要加载三维模型文件,可以使用GLTF格式。GLTF是一种基于JSON的开放标准,用于3D模型的交换和运行时加载。本篇文章将详细讲解如何使用Three.js加载GLTF模型。 ## 1. 下载GLTF模型 在开始之前,请确保您已经有一个GLTF模…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
