基于消息队列+多进程编写的银行模拟系统

news2024/9/21 12:34:35

银行模拟系统

  • 概述
  • 客户端 client.c
  • 服务端 serve.c
  • 开户 enroll.c
  • 存款 save.c
  • 转账 transfer.c
  • 取款 take.c
  • makefile文件

概述

  该案例大体过程为,服务器先启动,初始化消息队列和信号,用多线程技术启动开户、存钱、转账、取钱模块,并且可以控制结束。客户端启动后会自动链接服务器,会将用户的请求发送到请求队列,从响应消息队列读取处理结果,并提示给用户。其他模块轮询检测请求消息队列中是否有自己应该去做事情的消息,如果读取到就开始任务,并且将任务结果发送到响应消息队列。
  目前用户信息存取是通过txt文件实现的,每个用户单独一个文件。
  并且提供了makefile文件生成可执行文件,文件布局如下:

在这里插入图片描述

客户端 client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int reqid;//请求队列id
int resid;//响应队列id

typedef struct msgbuff
{
   long mtype;
   char name[20];
   char password[20];
   float money;
}user;

typedef struct resbuff
{
   long type;
   char name[20];
   char msg[256];
   float money;
}res;

void menu(void);				//菜单
void enroll(void);				//开户
void save_money(void);			//存钱
void transfer_money(void);		//转账
void take_money(void);			//取钱

int main(int argc,char *argv[])
{
   while(1)
   {
   	menu();
   }
}


void menu(void)
{
   system("clear");
   printf("\n\t欢迎使用wwz银行ATM机\n");
   printf("\t\t1:开户\n");
   printf("\t\t2:存钱\n");
   printf("\t\t3:转账\n");
   printf("\t\t4:取钱\n");
   printf("\t请输入1-4进行选择:\n");
   int key;
   scanf("%d",&key);
   switch(key)
   {
   	case 1 :	enroll();			break;
   	case 2 :	save_money();		break;
   	case 3 :	transfer_money();	break;
   	case 4 :	take_money();		break;
   default:printf("输入有误请重新输入\n");sleep(1);break;
   }
}
void enroll(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、存钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 1;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),1,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}
void save_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、存钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 2;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),2,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}
void transfer_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、转账金额、转账账户\n");
   user u1,u2;
   scanf("%s %s %f %s",u1.name,u1.password,&u1.money,u2.name);
   //发送到请求队列
   u1.mtype = 4;
   u2.mtype = 5;
   msgsnd(reqid,&u1,sizeof(user)-sizeof(long),0);
   msgsnd(reqid,&u2,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r1,r2;
   msgrcv(resid,&r1,sizeof(res),4,0);
   msgrcv(resid,&r2,sizeof(res),5,0);
   printf("%s\t",r1.msg);
   printf("%s",r2.msg);
   return;
}
void take_money(void)
{
   system("clear");
   //键值
   key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
   key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
   //打开请求消息队列
   reqid = msgget(key1,IPC_CREAT|0644);
   if(reqid== -1){perror("msgget");return;}
   //打开应答消息队列
   resid =msgget(key2,IPC_CREAT|0644);
   if(resid == -1){perror("msgget");return;}
   //读取信息
   printf("请输入用户名、密码、取钱金额\n");
   user u;
   scanf("%s %s %f",u.name,u.password,&u.money);
   //发送到请求队列
   u.mtype = 3;
   msgsnd(reqid,&u,sizeof(user)-sizeof(long),0);
   //接收请求结果
   res r;
   msgrcv(resid,&r,sizeof(res),3,0);  //1对应上面的1
   printf("%s",r.msg);
   return;
}

服务端 serve.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>

static int reqid = -1; //作为请求的消息队列的返回id
static int resid = -1;  //作为响应的消息队列的返回id

typedef struct Service{
    char path[256];
    pid_t pid;
}Srv;
static Srv srv[]={ 
    {"./out/enroll",-1},      	//开户
    {"./out/save",-1},      	//存款
    {"./out/take",-1},  		//取款
    {"./out/trans",-1},     	//转账
};

int Init_msg();				//初始化消息队列
void deInit_msg();			//销毁消息队列
void sigint(int signum);	//初始化信号
int start();				//启动服务器
int stop();					//关闭服务器

int main(int argc,char *argv[])
{
	atexit(deInit_msg);
	signal(SIGINT,sigint);
	if(Init_msg() == -1){return -1;}
    if(start() == -1){return -1;}
    sleep(1);
    //阻塞等待退出
    printf("按<回车>键退出......\n");
    getchar();
    if(stop() == -1){return -1;}
    return 0;
}
int Init_msg()
{
    printf("服务器初始化.....\n");
    
    //键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//创建
    reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
    printf("创建请求消息队列成功!\n");
    resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
    printf("创建应答消息队列成功!\n");
    return 0;
}
void deInit_msg()
{
    printf("服务器关闭.....\n");
    if(msgctl(reqid,IPC_RMID,NULL) == -1){perror("msgctl");}
    else	printf("销毁请求消息队列成功!\n");
    if(msgctl(resid,IPC_RMID,NULL) == -1)perror("msgctl");
    else	printf("销毁应答消息队列成功!\n");
}
void sigint(int signum)
{
    printf("%d\n",signum);
    stop();
    exit(0);
}

int start()
{
    printf("启动服务器\\n");
    size_t i;
    for(i=0; i<sizeof(srv)/sizeof(srv[0]); i++)
    {
        if((srv[i].pid = vfork()) == -1)
        {perror("vfork");return -1;}
        if(srv[i].pid == 0)
        {
            if(execl(srv[i].path,srv[i].path,NULL)==-1)
            {
                perror("execl");
                return -1;
            }
            return 0;
        }
    }
    return 0;
}
int stop()
{
    printf("关闭服务器\n");
    size_t i;
    for(i=0; i<sizeof(srv)/sizeof(srv[0]); i++)
    {
        if(kill(srv[i].pid,SIGINT) == -1)
        {
            perror("kill");
            return -1;
        }
    }
    for(;;)if(wait(NULL) == -1){perror("wait");break;}
    return 0;
}

开户 enroll.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;
//停止服务函数
void stop_fun(void)
{
	printf("开户服务停止\n");
	exit(0);
}
//保存信息函数
int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("开户服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),1,0)==-1)
		{perror ("msgrcv");continue;}
		
		printf("开户帐号:");
        printf("%s\n",req.name);
		
		res r;
		strcpy(r.name,req.name);
		//打开文件并且确认是否有该用户
		char temp[128]={0};
		sprintf(temp,"/home/wwz/xyd/bank/data/%s.txt",req.name);
		//只写,如果打不开就证明没有,能打开就是有了
		int fp = open(temp,O_WRONLY);
		
		if(fp>0)
		{
			r.type = 1;
			sprintf(r.msg,"已有该用户,开户失败!");
			msgsnd(resid,&r,sizeof(res)-sizeof(long),0);
		}
		else
		{
			save(&req);
			sprintf(r.msg,"开户成功!");
			msgsnd(resid,&r,sizeof(res)-sizeof(long),0);
		}
		close(fp);
	}
	return 0;
}

存款 save.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void * stop_fun(void)
{
	printf("存款服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("存款服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),2,0)==-1)
		{perror ("msgrcv");continue;}
        printf("存款帐号:%s\n",req.name);
		res r;
		user u;
		if(get(req.name,&u)==-1)
		{sprintf(r.msg,"无效账户");goto send;}
		
		if(strcmp(req.password,u.password)!=0)
		{sprintf(r.msg,"密码错误");goto send;}
		
		u.money += req.money;
		if(save(&u) == -1)
		{sprintf(r.msg,"存款失败");goto send;}
		r.money = u.money;
		sprintf(r.msg,"存款成功");
send:		
		r.type = 2;
		if(msgsnd(resid,&r,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

转账 transfer.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void  stop_fun(void)
{
	printf("转账服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out/",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out/",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	while(1)
	{
		//轮循等待从队列中读出数据
		user req1,req2;
		if(msgrcv(reqid,&req1,sizeof(user)-sizeof(long),4,0)==-1)
		{perror ("req1:msgrcv");continue;}
		if(msgrcv(reqid,&req2,sizeof(user)-sizeof(long),5,0)==-1)
		{perror ("req2:msgrcv");continue;}
		
		res r1,r2;
		user u1,u2;
		
		memset(r1.msg,0,sizeof(r1.msg));
		memset(r2.msg,0,sizeof(r2.msg));
		
		printf("转账帐号:%s  收款帐号:%s\n",req1.name,req2.name);
		
		if(get(req1.name,&u1)==-1)
		{strcpy(r1.msg,"转账账户为无效账户");goto send;}
		if(get(req2.name,&u2)==-1)
		{strcpy(r2.msg,"收款账户为无效账户");goto send;}
		if(strcmp(req1.password,u1.password))
		{strcpy(r1.msg,"密码错误");goto send;}
		if(req1.money>u1.money)
		{sprintf(r1.msg,"抱歉,余额不足,您的余额为:%f",u1.money);goto send;}
		u1.money -= req1.money;
		u2.money += req1.money;
		if(save(&u1) == -1)
		{strcpy(r1.msg,"转账失败");goto send;}
		if(save(&u2) == -1)
		{strcpy(r2.msg,"收款失败");goto send;}
		
		r1.money = u1.money;
		r2.money = u2.money;
		
		sprintf(r1.msg,"转账成功,您的余额为:%f",u1.money);
		strcpy(r2.msg,"收款成功");
send:		
		r1.type = 4;
		if(msgsnd(resid,&r1,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
send2:
		r2.type = 5;
		if(msgsnd(resid,&r2,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

取款 take.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

int reqid; 
int resid; 

typedef struct msgbuff
{
	long mtype;
	char name[20];
	char password[20];
	float money;
}user;

typedef struct resbuff
{
	long type;
	char name[20];
	char msg[256];
	float money;
}res;

void  stop_fun(void)
{
	printf("取款服务停止\n");
	exit(0);
}

int get(char name[20],user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",name);
	FILE * fp = fopen(pathname,"r");
	if(fp == NULL){perror("get:fopen");return -1;}
	fscanf(fp,"%s\t%s\t%f\n",u->name,u->password,&u->money);
	fclose(fp);
	return 1;
}

int save(const user *u)
{
	char pathname[256] = {0};
	sprintf(pathname,"/home/wwz/xyd/bank/data/%s.txt",u->name);
	FILE * fp = fopen(pathname,"w+");
	if(fp == NULL){perror("save:fopen");return -1;}
	fprintf(fp,"%s\t%s\t%lf\n",u->name,u->password,u->money);
	fclose(fp);
	return 0;
}

int main(int argc,char *argv[])
{
	signal(SIGINT,(void *)stop_fun);
	//键值
	key_t key1 = ftok("/home/wwz/xyd/bank/out/",1);
	key_t key2 = ftok("/home/wwz/xyd/bank/out/",2);
	//打开请求消息队列
	reqid = msgget(key1,IPC_CREAT|0644);
	if(reqid == -1){perror("msgget");return -1;}
	//打开应答消息队列
	resid = msgget(key2,IPC_CREAT|0644);
	if(resid == -1){perror("msgget");return -1;}
	
	printf("取款服务启动\n");
	while(1)
	{
		//轮循等待从队列中读出数据
		user req;
		if(msgrcv(reqid,&req,sizeof(req)-sizeof(long),3,0)==-1)
		{perror ("msgrcv");continue;}
		printf("取款帐号:%s\n",req.name);
		res r;
		user u;
		if(get(req.name,&u)==-1)
		{strcpy(r.msg,"无效账户");goto send;}
		if(strcmp(req.password,u.password))
		{strcpy(r.msg,"密码错误");goto send;}
		if(req.money>u.money)
		{sprintf(r.msg,"抱歉,余额不足,您的余额为:%f",u.money);goto send;}
		u.money -= req.money;
		if(save(&u) == -1)
		{strcpy(r.msg,"取款失败");goto send;}
		r.money = u.money;
		sprintf(r.msg,"取款成功,您的余额为:%f",u.money);
send:		
		r.type = 3;
		if(msgsnd(resid,&r,sizeof(res)-sizeof(long),0)==-1)
        {perror("msgsnd");continue;}
	}
	return 0;
}

makefile文件

all:serve client ./out/enroll ./out/save ./out/take ./out/trans
obj = $(wildcard ./src/*.c)

serve:$(obj)
	gcc  ./src/serve.c -o $@
client:$(obj)
	gcc  ./src/client.c -o $@
./out/enroll:$(obj)
	gcc  ./src/enroll.c -o $@
./out/save:$(obj)
	gcc ./src/save.c -o $@
./out/take:$(obj)
	gcc  ./src/take.c -o $@
./out/trans:$(obj)
	gcc  ./src/transfer.c -o $@

clean:
	rm serve client ./out/enroll ./out/save ./out/take ./out/trans
.PHONY:clean

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1212345.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础-解释器安装

一、下载 网址Welcome to Python.orgPython更新到13了&#xff0c;我们安装上一个12版本。 这里我保存到网盘里了&#xff0c;不想从官网下的&#xff0c;可以直接从网盘里下载。 链接&#xff1a;百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间…

IDEA从Gitee拉取代码,推送代码教程

打开IDEA&#xff0c;选择Get from Version Control 输入Gitee 仓库项目的URL地址 URL地址输入后点击Clone&#xff0c;即拉取成功 向Gitee提交推送代码 右键选中项目&#xff0c;选中Git 第一步先点击 Add 第二步 点击Commit填写提交信息&#xff0c;点击Commit就会出现下面…

Jenkins的一些其他操作

Jenkins的一些其他操作 1、代码仓库Gogs的搭建与配置 Gogs 是一款极易搭建的自助 Git 服务&#xff0c;它的目标在于打造一个最简单、快速和轻松的方式搭建 Git 服务。使用 Go 语言开发的它能够通过独立的二进制进行分发&#xff0c;支持了 Go 语言支持的所有平台&#xff0…

Vue修饰符(Vue事件修饰符、Vue按键修饰符)

目录 前言 Vue事件修饰符 列举较常用的事件修饰符 .stop .prevent .capture .once Vue按键修饰符 四个特殊键 获取某个键的按键修饰符 前言 本文介绍Vue修饰符&#xff0c;包括Vue事件修饰符以及按键修饰符 Vue事件修饰符 列举较常用的事件修饰符 .stop: …

【Linux基础IO篇】深入理解文件系统、动静态库

【Linux基础IO篇】深入理解文件系统、动静态库 目录 【Linux基础IO篇】深入理解文件系统、动静态库再次理解文件系统操作系统内存管理模块&#xff08;基础&#xff09;操作系统如何管理内存 Linux中task_struct源码结构 动态库和静态库动静态库介绍&#xff1a;生成静态库库搜…

IDEA安装配置SceneBuilder

1、下载 SceneBuilder 地址&#xff1a; Scene Builder - Gluon ​​​​​​​ Scene Builder | JavaFX中文官方网站 选择符合自己系统版本&#xff0c;JAVA版本的下载 2、安装SceneBuilder 执行下载的 SceneBuilder 安装程序&#xff0c;并按照安装向导的指示进行…

Pikachu漏洞练习平台之CSRF(跨站请求伪造)

本质&#xff1a;挟制用户在当前已登录的Web应用程序上执行非本意的操作&#xff08;由客户端发起&#xff09; 耐心看完皮卡丘靶场的这个例子你就明白什么是CSRF了 CSRF(get) 使用提示里给的用户和密码进行登录&#xff08;这里以lili为例&#xff09; 登录成功后显示用户…

(Matalb时序预测)GWO-BP灰狼算法优化BP神经网络的多维时序回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分代码展示&#xff1a; 四、完整代码数据说明手册下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于M…

SSH-远程连接服务器

一、理论知识 目前远程连接服务器的主要类型&#xff1a; 文字接口明文传输&#xff1a;Telnet、RSH 等为主&#xff0c;目前非常少用。文字接口加密&#xff1a;SSH 为主&#xff0c;已经取代上述的 Telnet、RSH 等明文传输方式。图形接口&#xff1a;XDMCP&#xff08;X Di…

Neo4j数据库介绍及简单使用

图数据库介绍 图数据库是一种专门设计用于存储和管理图形数据的数据库类型。在图数据库中&#xff0c;数据以图的形式表示&#xff0c;其中节点表示实体&#xff0c;边表示实体之间的关系。这种表示方式非常适合处理具有复杂关系的数据&#xff0c;如社交网络、推荐系统、网络…

安装部署PowerDNS--实现内网DNS解析(use)

使用PowerDNS实现内网DNS解析_powerdns-admin-CSDN博客 https://www.cnblogs.com/guangdelw/p/17348982.html 一、概念介绍 PowerDNS是一个域名解析服务&#xff0c;官网提供了三个组件&#xff1a;Authoritative、Recursor、dnsdist&#xff0c;分别用来作为权威服务器、域名递…

Leetcode——岛屿的最大面积

1. 题目链接&#xff1a;695. 岛屿的最大面积 2. 题目描述&#xff1a; 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都…

ssh脚本找不到命令或者执行无效的解决办法

如图&#xff1a;今天在编写脚本时发现的这个问题&#xff0c; 在排除脚本语法错误、编码格式等情况下&#xff0c;仍然出现“bash 。。未找到命令”的字样 解决办法&#xff1a; 给每台虚拟机的环境变量source一下&#xff1a; 命令如下 source /etc/profile或者输入 vim ~…

【数据结构】直接选择排序(你知道最不常用的排序算法有哪些吗?)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…

【2023云栖】黄博远:阿里云人工智能平台PAI年度发布

本文根据2023云栖大会演讲实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;黄博远 | 阿里云计算平台事业部资深产品专家、阿里云人工智能平台PAI产品负责人 演讲主题&#xff1a;阿里云人工智能平台PAI年度发布 AIGC是我们这个时代的新机遇 今年云栖大…

单相过压继电器DVR-G-100-1 0~500V AC/DC220V 导轨安装

系列型号 DVR-G-100-1X3数字式过压继电器&#xff1b; DVR-G-100-3三相过压继电器&#xff1b; DVR(H)-G-100-1单相过压继电器&#xff1b; DVR-Q-100-3三相欠压继电器&#xff1b; DVR(H)-Q-100-3三相欠压继电器 一、用途 主要应用于电机、变压器等主设备以及输配电系统的继…

人工智能与大数据:驱动现代业务转型的双引擎

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和大数据已成为驱动业务和技术创新的关键力量。它们的结合不仅重塑了传统行业&#xff0c;也催生了新的商业模式和服务方式。 AI与大数据在零售行业的应用 在零售行业&#xff0c;AI和大数据的应用已经成为提…

代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和

LeetCode T1143 最长公共子序列 题目链接:1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 动规五部曲分析 1.确定dp数组的含义 这里dp数组的含义是结尾分别为i-1,j-1的text1和text2的最长公共子序列长度 至于为什么是i-1,j-1我之前已经说过了,这里再…

电池故障估计:Realistic fault detection of li-ion battery via dynamical deep learning

昇科能源、清华大学欧阳明高院士团队等的最新研究成果《动态深度学习实现锂离子电池异常检测》&#xff0c;用已经处理的整车充电段数据&#xff0c;分析车辆当前或近期是否存在故障。 思想步骤&#xff1a; 用正常电池的充电片段数据构造训练集&#xff0c;用如下的方式构造…

重生奇迹mu圣导师加点

重生奇迹mu圣导师加点&#xff1a;要攻击高可以加力量&#xff0c;平衡系建议加点力量600~800&#xff0c;智力200~400&#xff0c;敏够装备要求&#xff0c;统帅1000&#xff0c;其余加体力。 圣导师靠加力量培养高攻圣导师不现实&#xff0c;建议玩家练魔&#xff0c;低级圣…