linux 下用C实现 银行小系统 (进程间通信)—— ATM

30 篇文章 1 订阅

项目需求:

主要分为两人大模块:
	
	客户端
		1、进入时的功能开户、销户、登录、解锁
			开户:输入姓名、身份证号、设置密码,如果开户成功,则服务器上保存一个账号信号(一个账号存一个文件,文件名建议是账号)。
			销户:输入帐号、密码,服务器询问是否确认销户,如果确认则服务器删除帐号文件,并记录帐号。(我没实现)
			登录:输入账号、密码,三次错误账号锁定。
			解锁:输入账号、身份证号解锁。
		2、登录成功:存钱、取钱、转账、查询、修改密码
			存钱:输入存钱金额
			取钱:输入取钱金额
			转账:目标帐号和要转的金额
			查询:不需要输入数据
			修改密码:原密码和新密码
	服务器
		如果识别功能:根据消息的类型识别客户端请求的功能。
		开启服务各项功能的子进程
			各进程按照消息类型接收消息

码云传送门,github:传送门

直接先上图:

打开2个终端,一个 make编译所有文件

然后运行 ./server(服务端)

另一个终端运行 ./client(客户端)

切记不要关闭服务端。

接下来在客户端进行操作。

1、开户(客户端)

(服务端)会输出相关信息

2、销户

(客户端)

(服务端)

3、登录

(客户端)

(服务端)

登录后(子功能)

具体就不在列举了,下面提供部分源码,具体请移步码云传送门GitHub传送门

server.c

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include "struct.h"
#include "tools.h"

// 2个消息队列
static int msgid_ctos;
static int msgid_stoc;
// 存储子进程ID
static pid_t sub_pid[9];

// SIGINT信号处理
void sigint(int sig)
{
    // 对msqid标识的消息队列执行cmd操作
	msgctl(msgid_ctos, IPC_RMID, NULL);
	msgctl(msgid_stoc, IPC_RMID, NULL);
	
	int i = 0;
	for(i=0; i<9; i++)
	{
		kill(sub_pid[i], SIGKILL);
	}
}

int main()
{ 
    // 处理信号 SIGINT(2) 终端中断符信号 
	signal(SIGINT, sigint);

    // int msgctl(int msqid, int cmd, struct msqid_ds *buf);
	msgctl(msgid_ctos, IPC_RMID, NULL);
	msgctl(msgid_stoc, IPC_RMID, NULL);

    // IPC_CREAT 创建消息队列,IPC_EXCL 如果存在则创建失败
    // IPC键值,由ftok函数自动生成
	msgid_ctos = msgget(ftok(".", 100), IPC_CREAT|IPC_EXCL|0644);
	msgid_stoc = msgget(ftok(".", 200), IPC_CREAT|IPC_EXCL|0644);
	
    // login open save take transf select change destory unlock
    // 创建一个新的进程
	sub_pid[0] = vfork();
	if(0 == sub_pid[0])
	{
		execl("login","login", NULL);
		printf("登陆子进程创建成功...\n");
	}

	sub_pid[1] = vfork();
	if(0 == sub_pid[1])
	{
		execl("open","open", NULL);
		printf("开户子进程创建成功...\n");
	}
	sub_pid[2] = vfork();
	if(0 == sub_pid[2])
	{
		execl("save","save", NULL);
	}
	
	sub_pid[3] = vfork();
	if(0 == sub_pid[3])
	{
		execl("take","take", NULL);
	}
	
	sub_pid[4] = vfork();
	if(0 == sub_pid[4])
	{
		execl("transf","transf", NULL);
	}

	sub_pid[5] = vfork();
	if(0 == sub_pid[5])
	{
		execl("select","select", NULL);
	}

	sub_pid[6] = vfork();
	if(0 == sub_pid[6])
	{
		execl("change","change", NULL);
	}	

	sub_pid[7] = vfork();
	if(0 == sub_pid[7])
	{
		execl("destory","destory", NULL);
	}

	sub_pid[8] = vfork();
	if(0 == sub_pid[8])
	{
		execl("unlock","unlock", NULL);
	}

	//pause();
	while(-1 != wait(NULL));
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include "struct.h"
#include "tools.h"
//#include "msg_queue.c"

static long online = 0;
static int lock = 0;

int msgid_ctos;
int msgid_stoc;

// 初始化
int init();
// 创建账户
void open_acc();
// 销毁账户
void destory();
// 登录
void login();
// 解锁
void unlock();
// 用户菜单
void user_menu(void);
// 主菜单
void menu(void);
// 存钱
void save();
// 取钱
void take();
// 转账
void transf();
// 查询余额
void select_money();
// 修改密码
void change_pw();

int main()
{
	init();
	menu();
}

// 初始化
int init()
{
	//msgctl(msgid_ctos,IPC_RMID,NULL);
	// 创建消息队列
	msgid_ctos = msgget(ftok(".",100),0);
	if(0 > msgid_ctos)
	{
		perror("msgget");
		return -1;
	}
	msgid_stoc = msgget(ftok(".",200),0);
	if(0 > msgid_stoc)
	{
		perror("msgget");
		return -1;
	}
	return 0;
}

// 登录
void login()//0
{
	if(lock >= 3)
	{
		printf("您已被锁定,请解锁\n");
		getchar();
		return;
	}
	Account acc = {};
	Msg msg = {110};
	printf("请输入帐号:");
	scanf("%ld",&acc.user);
	getchar();
	printf("请输入密码:");
	get_str(acc.pw,20);
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),220,MSG_NOERROR);
	
	if(acc.user == msg2.acc.user)
	{
		online = acc.user;
		printf("%ld,登陆成功\n",online);
		getch();
		user_menu();
	}
	else
	{	
		lock++;	
		printf("帐号或密码错误\n");
		getch();
	}
}

// 创建账户
void open_acc()//1
{

	Account acc = {};
	Msg msg = {111};
	printf("请输入姓名:");
	get_str(acc.name,20);
	printf("请输入身份证:");
	get_str(acc.id,20);
	printf("请输入密码:");
	get_str(acc.pw,20);
	msg.acc = acc;
	//printf("msg:%s\n",msg.acc.name);
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),221,MSG_NOERROR);
	printf("msg2:%s,acc:%s\n",msg2.acc.name,acc.name);
	if(strcmp(acc.name,msg2.acc.name) == 0)
	{
		//printf("%s\n",msg2.acc.name);
		//printf("%s\n",msg2.acc.id);
		printf("帐号:%ld,开户成功\n",msg2.acc.user);
	}
	else
	{		
		printf("开户失败\n");
	}
	getch();
}

// 存钱
void save()//2
{
	Account acc = {};
	Msg msg = {112};
	//printf("当前用户:%ld\n",online);
	printf("请输入存款金额:");
	scanf("%lf",&acc.money);
	getchar();
	acc.user = online;	
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),222,MSG_NOERROR);
	if(msg2.acc.user == online)
	{
		printf("存钱成功\n");
	}
	else
	{
		printf("存钱失败\n");
	}
	getch();
}

// 取钱
void take()//3
{
	Account acc = {};
	Msg msg = {113};
	printf("请输入取款金额:");
	scanf("%lf",&acc.money);
	getchar();
	acc.user = online;	
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),223,MSG_NOERROR);
	if(msg2.acc.user == online)
	{
		printf("取钱成功\n");
	}
	else if(msg2.acc.user == online + 2)
	{
		printf("余额不足,请充值\n");
	}
	else
	{
		printf("取钱失败\n");
	}
	getch();
}

// 转账
void transf()//4
{
	Account acc = {};
	Msg msg = {114};
	printf("请输入转帐金额:");
	scanf("%lf",&acc.money);
	getchar();
	acc.user = online;	
	msg.acc = acc;
	msg.flag = 0;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),224,MSG_NOERROR);
	if(msg2.flag == 0)
	{
		printf("请输入要转帐的帐号:");
		scanf("%ld",&acc.user);
		getchar();
		msg.acc = acc;
		msg.flag = 1;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);
		
		// 接收消息
		msgrcv(msgid_stoc,&msg2,sizeof(Msg),224,MSG_NOERROR);
		
		if(msg2.flag == 2)
		{
			printf("转帐成功\n");
		}
		else
		{
			printf("转帐失败\n");
		}
			
	}
	else
	{
		printf("余额不足,请充值\n");
	}
	getch();
}

// 查询余额
void select_money()//5
{
	Account acc = {};
	Msg msg = {115};
	acc.user = online;	
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),225,MSG_NOERROR);
	if(msg2.acc.user == online)
	{
		printf("余额:%.2lf\n",msg2.acc.money);
	}
	else
	{
		printf("查询失败\n");
	}
	getch();
}

// 修改密码
void change_pw()//6
{
	Account acc = {};
	Msg msg = {116};
	printf("请输入新密码:");
	get_str(acc.pw,20);
	acc.user = online;	
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),226,MSG_NOERROR);
	if(msg2.acc.user == online)
	{
		printf("改密成功\n");
	}
	else
	{
		printf("改密失败\n");
	}
	getch();
}

// 销毁账户
void destory()//7
{
	Account acc = {};
	Msg msg = {117};
	printf("请输入销户帐号:");
	scanf("%ld",&acc.user);
	getchar();
	printf("请输入姓名:");
	get_str(acc.name,20);
	printf("请输入身份证:");
	get_str(acc.id,20);
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),227,MSG_NOERROR);
	if(msg2.acc.user == 0)
	{
		printf("销户成功\n");
	}
	else if(msg2.acc.user == 1)
	{
		printf("相关信息错误\n");
	}
	else if(msg2.acc.user == 2)
	{
		printf("帐号不存在\n");
	}
	getch();
}

// 解锁账户
void unlock()//8
{
	if(lock < 3)
	{
		printf("您没有被锁定,sorry\n");
		getchar();
		return;
	}
	Account acc = {};
	Msg msg = {118};
	printf("请输入帐号:");
	scanf("%ld",&acc.user);
	getchar();
	printf("请输入姓名:");
	get_str(acc.name,20);
	printf("请输入身份证:");
	get_str(acc.id,20);
	msg.acc = acc;
	msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),0);

	//printf("消息已发送到队列\n");

	Msg msg2 = {};
	// 接收消息
	msgrcv(msgid_stoc,&msg2,sizeof(Msg),228,MSG_NOERROR);
	
	//printf("已接收到队列的消息\n");
	printf("in:%ld,back:%ld\n",acc.user,msg2.acc.user);
	
	if(acc.user == msg2.acc.user)
	{
		printf("%ld,解锁成功\n",acc.user);
		lock = 0;
		online = acc.user;
		change_pw();
	}
	else
	{	
		printf("相关信息错误\n");
		getch();
	}

/*	long user = 0;
	char id[20] = {};
	char name[20] = {};
	printf("请输入要解锁的帐号:");
	scanf("%ld",&user);
	getchar();

	char path[50] = "./data/";
	char ex[8] = ".dat";
	sprintf(path,"%s%ld%s",path,user,ex);

	if(0 == access(path,F_OK))
	{
		Account buf = {};
		int fd = open(path,O_RDWR);
		if(0 != read(fd,&buf,sizeof(Account)))
		{
			char name[20] = {};
			char id[20] = {};
			printf("请输入此帐号开户姓名:");
			get_str(name,20);
			printf("请输入此帐号开户身份证:");
			get_str(id,20);

			if(strcmp(name,buf.name) == 0 && strcmp(id,buf.id) == 0)
			{
				online = user;
				change_pw();
				lock = 0;
			}
			else
			{
				printf("输入信息有误\n");
				close(fd);
				getch();
			}
		}
		else
		{
			printf("读取信息失败\n");
			getch();
		}
	}
	else
	{
		printf("此帐号不存在\n");
		getch();
	}
*/
}

// 用户菜单
void user_menu(void)
{
	while(1)
	{
		system("clear");
		printf("---  银行  ---\n");
		printf("1、  存钱\n");
		printf("2、  取钱\n");
		printf("3、  转帐\n");
		printf("4、  查询\n");
		printf("5、  改密\n");
		printf("0、  返回\n");
		switch(get_cmd('0','5'))
		{
			case '1':save(); break;
			case '2':take(); break;
			case '3':transf(); break;
			case '4':select_money(); break;
			case '5':change_pw();break;
			case '0':return;
		}
	}
}

// 主菜单
void menu(void)
{
	while(1)
	{
		system("clear");
		printf("---  银行  ---\n");
		printf("1、  开户\n");
		printf("2、  销户\n");
		printf("3、  登陆\n");
		printf("4、  解锁\n");
		printf("0、  退出\n");
		switch(get_cmd('0','4'))
		{
			case '1':open_acc(); break;
			case '2':destory(); break;
			case '3':login(); break;
			case '4':unlock(); break;
			case '0':return;
		}
	}
}

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love丶伊卡洛斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值