Linux用消息队列完成进程间本地通讯的ATM机

ATM项目主要分为两人大模块:

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

代码如下

  • 客户端

client.c

//登陆后的功能
#include "tools.h"
#include "cfunc.h"
#include "struct.h"

int main()
{
	while(1)
	{
		show();
		switch(get_cmd('1','5'))
		{
			case '1':open();break;
			case '2':entry();break;
			case '3':destory();break;
			case '4':unlock();break;
			case '5':puts("谢谢使用!");return 0;
		}
	}
}

cfunc.c

#include "cfunc.h"

static int msgid1;
static int msgid2;

int get_msg(void)
{
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
}

//开户
void open(void)
{
	struct User use;
	printf("请输入你的姓名:");
	scanf("%s",use.name);
	printf("请输入你的身份证号码:");
	scanf("%lld",&use.id);
	printf("请输入你的密码:");
	get_pd(use.pass,9);
	printf("请输入开户预存金额:");
	while(1)
	{
		scanf("%lf",&use.money);
		if(use.money > 0 && use.money <10000000000000000) break;
		else printf("金额输入不合法,请重新输入:");
	}
	clear_stdin();	
	use.cnt = 3;
	use.lock = 0;
    struct Msg msg = {1,use};
    get_msg();
    int i = msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
    msgrcv(msgid2,&msg,sizeof(Msg),1,0);
    if(msg.type == 1)
    {
 	  	printf("开户成功!\n");
        printf("您的卡号:%d\n",msg.use.card_id);
        clear_stdin();
        anykey_continue();
    }
    else
    {
        printf("开户失败!\n");
    }
 }

//存款
void save(int num)
{
	struct User use;
	use.card_id = num;
	printf("请输入您要储存的金额:");
	while(1)
	{
		scanf("%lf",&use.money);
		if(use.money > 0 && use.money <10000000000000000) break;
		else printf("金额输入不合法,请重新输入:");
	}
	get_msg();
	struct Msg msg = {2,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),2,0);
	if(msg.type == 2)
    {
 	  	printf("储存成功!\n");
        printf("您的余额:%.2lf\n",msg.use.money);
        clear_stdin();
        anykey_continue();
    }
    else
    {
        printf("储存失败!\n");
    }
}

//取款
void extract(int num)
{
	struct User use;
	use.card_id = num;
	printf("请输入您要取出的金额:");
	while(1)
	{
		scanf("%lf",&use.money);
		if(use.money > 0 && use.money <10000000000000000) break;
		else printf("金额输入不合法,请重新输入:");
	}
	get_msg();
	struct Msg msg = {3,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),3,0);
	if(msg.use.money != -1)
    {
 	  	printf("取款成功!\n");
        printf("您的余额:%.2lf\n",msg.use.money);
        clear_stdin();
        anykey_continue();
    }
    else
    {
        printf("余额不足,取款失败!\n");
        sleep(1);
    }
}

//查询
void inquiry(int num)
{
	struct User use={};
	use.card_id = num;
	get_msg();
	struct Msg msg = {4,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),4,0);
	if(msg.use.card_id == use.card_id)
    {
        printf("您的卡号:%d\n",msg.use.card_id);
        printf("您的姓名:%s\n",msg.use.name);
        printf("您的余额:%.2lf\n",msg.use.money);
        clear_stdin();
        anykey_continue();
    }
    else
    {
        printf("查询失败!\n");
    }
}

//转账
void transfer(int num)
{		
	struct User use;
	use.card_id = num;
	printf("请输入您要转账的金额:");
	while(1)
	{
		scanf("%lf",&use.money);
		if(use.money > 0 && use.money <10000000000000000) break;
		else printf("金额输入不合法,请重新输入:");
	}		
	get_msg();
	struct Msg msg = {5,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),5,0);
	if(msg.use.money == use.money)
    {		
		struct User use1;		
		while(1)
		{	
			printf("请输入您要转账的卡号:");
			scanf("%d",&use1.card_id);
			if(use1.card_id != num) break;
			else printf("无法给自己账户转账(无意义操作)\n");
		}
		use1.money = use.money;
		get_msg();
		struct Msg msg1 = {10,use1};
		msgsnd(msgid1,&msg1,sizeof(Msg)-4,0);
		msgrcv(msgid2,&msg1,sizeof(Msg),10,0);
		if(msg1.use.card_id != -1)
   		{
 			printf("转账成功!\n");
        	clear_stdin();
        	anykey_continue();
    	}
    	else
    	{	
    		printf("转账账户不存在,转账失败!\n");
    		anykey_continue();
    	}
    }
    else
    {
        printf("卡号余额不足,转账失败!\n");
        anykey_continue();
    }
}

//修改密码
void changepass(int num)
{
	struct User use={};
	use.card_id = num;
	char str1[9] = {},str2[9] = {};
	while(1)
	{
		printf("请输入您的新密码:");
		get_pd(str1,9);
		printf("请再输入您的新密码:");
		get_pd(str2,9);
		if(0 == strcmp(str1,str2)) break;
		else printf("两次密码输入不同,请重新输入!/n");
	}
	strcpy(use.pass,str1);
	get_msg();
	struct Msg msg = {8,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),8,0);
	if(msg.use.card_id == use.card_id)
    {
        printf("修改成功\n");
        clear_stdin();
        anykey_continue();
    }
    else
    {
        printf("修改失败!\n");
    }
}

//登录
void entry(void)
{
	struct User use;
	printf("请输入您的卡号:");
	while(1)
	{
		scanf("%d",&use.card_id);
		if(use.card_id >= 18000000 && use.card_id <= 18999999) break;
		else printf("格式错误,请重新输入卡号:");
	}
	printf("请输入您的密码:");
	get_pd(use.pass,9);
	get_msg();
	struct Msg msg = {7,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),7,0);
	if(msg.use.card_id == use.card_id)
    {
 	  	printf("登录成功!\n");
 	  	sleep(1);
 	  	func(msg.use.card_id);
    }
    else if(-1 == msg.use.card_id && 0 == msg.use.lock)
    {
    	printf("卡号与密码不匹配,登录失败,还有%d次\n",msg.use.cnt);
    	sleep(1);
    }
    else if(-2 == msg.use.card_id)
    {
    	printf("无该卡号,无法登陆!\n");
    	sleep(1);
    }
    else 
    {
    	printf("卡号已被锁定!\n");
		sleep(1);
	}
}

//销户
void destory(void)
{
	struct User use;
	printf("请输入您的卡号:");
	while(1)
	{
		scanf("%d",&use.card_id);
		if(use.card_id >= 18000000 && use.card_id <= 18999999) break;
		else printf("格式错误,请重新输入卡号:");
	}
	printf("请输入您的密码:");
	get_pd(use.pass,9);
	get_msg();
	struct Msg msg = {6,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),6,0);
	if(msg.use.card_id != -1)
	{
		printf("销户成功\n");
		clear_stdin();
        anykey_continue();
	}
	else
	{
		printf("卡号和密码不匹配或你的账户有余额,销户失败\n");
		sleep(1);
	}
}
//解锁
void unlock(void)
{
	struct User use;
	printf("请输入您的卡号:");
	while(1)
	{
		scanf("%d",&use.card_id);
		if(use.card_id >= 18000000 && use.card_id <= 18999999) break;
		else printf("格式错误,请重新输入卡号:");
	}
	printf("请输入您的身份证号码:");
	scanf("%lld",&use.id);
	get_msg();
	struct Msg msg = {9,use};
	msgsnd(msgid1,&msg,sizeof(Msg)-4,0);
	msgrcv(msgid2,&msg,sizeof(Msg),9,0);
	if(msg.use.card_id == use.card_id && msg.use.id == use.id)
    {
 	  	printf("解锁成功!\n");
 	  	sleep(1);
    }
    else if(-1 == msg.use.lock)
    {
    	printf("卡号未被锁定!");
    	sleep(1);
    }
    else 
    {
    	printf("卡号与身份证号码不匹配,解锁失败!\n");
		sleep(1);
	}
}

void func(int num)
{
	while(1)
	{
		display();
		switch(get_cmd('1','6'))
		{
			case '1':save(num);break;
			case '2':extract(num);break;
			case '3':inquiry(num);break;
			case '4':transfer(num);break;
			case '5':changepass(num);break;
			case '6':return;
		}
	}
}

cfunc.h

#ifndef CFUNC_H
#define CFUNC_H
#include "tools.h"
#include "struct.h"

int get_msg(void);

void open(void);

void save(int num);

void entry(void);

void extract(int num);

void inquiry(int num);

void transfer(int num);

void changepass(int num);

void unlock(void);

void destory(void);

void func(int num);

#endif //CEUNC_H

- 服务端

server.c

//服务端
#include "tools.h"
#include "struct.h"
#include "sys/wait.h"

static int msgid1;
static int msgid2;
static pid_t pid[9];

//销毁消息队列
void sigint(int num)
{	
	printf("服务器正在关闭..\n");
    sleep(2);
    if(msgctl(msgid1,IPC_RMID,NULL) == -1)
    {
    	perror("消息队列1删除失败\n");
        exit(-1);
    } 
    else
    {
	    printf("消息队列1删除成功\n");
    }
    if(msgctl(msgid2,IPC_RMID,NULL) == -1){
        perror("消息队列2删除失败\n");
        exit(-1);
    }
    else
    {
        printf("消息队列2删除成功\n");
    }
    for(int i=0;i<9;i++)
    {
    	kill(pid[i],SIGINT);
    }
    printf("服务器成功关闭\n");
    exit(0);//直接结束程序
}	

int main()
{
	printf("退出服务器请按CTRL+C\n");
    signal(SIGINT,sigint);
    //开户
    pid[0]=vfork();
	if(0 == pid[0])
	{	
		execl("open","open",NULL);
		exit(0);	
	}
	else perror("open");
	//存款
	pid[1]=vfork();
	if(0 == pid[1])
	{
		execl("save","save",NULL);
		exit(0);
	}
	else perror("save");
	//取款
	pid[2]=vfork();
	if(0 == pid[2])
	{	
		execl("extract","extract",NULL);
		exit(0);
	}
	else perror("extract");
	//查询
	pid[3]=vfork();
	if(0 == pid[3])
	{
		execl("inquiry","inquiry",NULL);
		exit(0);
	}
	else perror("inquiry");
	//转账
	pid[4]=vfork();
	if(0 == pid[4])	
	{	
		execl("transfer","transfer",NULL);
		exit(0);
	}
	else perror("transfer");
	//销户
	pid[5]=vfork();
	if(0 == pid[5])
	{
		execl("destory","destory",NULL);
		exit(0);
	}
	else perror("destory");
	//登录
	pid[6]=vfork();
	if(0 == pid[6])
	{	
		execl("entry","entry",NULL);
		exit(0);
	}
	else perror("entry");
	//修改密码
	pid[7]=vfork();
	if(0 == pid[7])
	{	
		execl("changepass","changepass",NULL);
		exit(0);
	}
	else perror("changepass");
	//解锁卡号
	pid[8]=vfork();
	if(0 == pid[8])
	{	
		execl("unlock","unlock",NULL);
		exit(0);
	}
	else perror("unlock");
	
	while(-1 == wait(0));
}

changepass.c

//服务端修改密码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <signal.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{	
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),8,0);
		struct User use;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("查询失败");
			return -1;
		}
		if(read(fd,&use,sizeof(User)) < 0) return -1;
		strcpy(use.pass,msg.use.pass);
		lseek(fd,0,SEEK_SET);	
        write(fd,&use,sizeof(User));
		close(fd);
		msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	}
}

destory.c

//服务端销户
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <signal.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),6,0);
		struct User use;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		//判断文件是否存在
		if(access(filename,F_OK) == -1)
		{
			msg.use.card_id = -1;
            msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
            continue;
        }
		int fd = open(filename,O_RDWR,00644);
		if(fd < 0)
		{
			msg.use.card_id = -1;
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		if(read(fd,&use,sizeof(User)) < 0) return -1;
		//当密码和卡号对应并且没有余额才能销户
		if(0 == strcmp(use.pass,msg.use.pass) && use.card_id == msg.use.card_id && use.money <= 0)
		{
			remove(filename);
	    	msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	    }
	    else
	    {
	    	msg.use.card_id = -1;
	    	msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	    }
    }
}

entry.c

//服务端登录
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <signal.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),7,0);
		struct User use;
		char filename[100]={".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		if(access(filename,F_OK) == -1)
		{
			msg.use.card_id = -2;
            msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
            continue;
        }
		int fd = open(filename,O_RDWR,00644);
		if(fd < 0)
		{
			msg.use.card_id = -1;
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		if(read(fd,&use,sizeof(User)) < 0) return -1;
		//需要卡号和密码相对应并且未被锁定
		if(0 == strcmp(use.pass,msg.use.pass) && use.card_id == msg.use.card_id && use.lock != 1)
		{
			//登陆成功次数重新开始计数
			use.cnt = 3;
			lseek(fd,0,SEEK_SET);	
        	write(fd,&use,sizeof(User));
			close(fd);
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		else
		{	//判断卡号是否被锁住
			if(use.lock != 1)
			{	//未被锁则记录次数
				msg.use.card_id = -1;
				use.cnt--;
				msg.use.cnt = use.cnt;
				if(0 == use.cnt) 
				{
					use.lock = 1;
					msg.use.lock = 1;		
				}				
				lseek(fd,0,SEEK_SET);	
        		write(fd,&use,sizeof(User));
        		close(fd);
				msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
			}
			else
			{	//锁住标志位lock至1
				msg.use.lock = 1;
				msg.use.card_id = -1;
				close(fd);
				msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
			}						
		}
	}
}

extract.c

//服务端取款
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <fcntl.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),3,0);
		struct User use1;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("取款失败");
			return -1;
		}
		if(read(fd,&use1,sizeof(User)) < 0) return -1;
		//如果余额不够取款的钱则取款失败
		if(use1.money < msg.use.money)
		{
			msg.use.money = -1;
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		else
		{
			use1.money -= msg.use.money;
        	lseek(fd,0,SEEK_SET);	
           	write(fd,&use1,sizeof(User));
	       	msg.use.money = use1.money;	    
			close(fd);
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
	}
}		

inquiry.c

//服务端查询
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <fcntl.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),4,0);
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("查询失败");
			return -1;
		}
		if(read(fd,&msg.use,sizeof(User)) < 0) return -1;
		close(fd);
		msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	}
}

open.c

//服务端开户
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <signal.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	static int num = 18000000;
	while(1)
	{
		struct Msg msg={};			
		msgrcv(msgid1,&msg,sizeof(Msg),1,0);
		msg.use.card_id = num++;
		char filename[100]={".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		int fd = open(filename,O_RDWR|O_CREAT|O_EXCL,00644);
		if(fd < 0)
		{
			perror("open");
			return -1;
		}
		if(write(fd,&msg.use,sizeof(User)) < 0) return -1;
		close(fd);
		msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	}	
}

save.c

//服务端存款
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <fcntl.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),2,0);
		struct User use1;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("存款失败");
			return -1;
		}
		if(read(fd,&use1,sizeof(User)) < 0) return -1;
		use1.money += msg.use.money;
	    lseek(fd,0,SEEK_SET);
	   	write(fd,&use1,sizeof(User));
	   	msg.use.money = use1.money;
		close(fd);
		msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
	}
}

transfer.c

//服务端转账
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <fcntl.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{	
		struct Msg msg1 = {};
		msgrcv(msgid1,&msg1,sizeof(Msg),5,0);
		struct User use1;
		char filename1[100] = {".dat"};
		sprintf(filename1,"./data/%d.dat",msg1.use.card_id);
		int fd1 = open(filename1,O_RDWR,00644);
		if(fd1 == -1)
		{
			perror("转账失败");
			return -1;
		}
		if(read(fd1,&use1,sizeof(User)) < 0) return -1;
		//判断余额是否大于转账金额
		if(use1.money < msg1.use.money)
		{
			msg1.use.money = -1;
			msgsnd(msgid2,&msg1,sizeof(Msg)-4,0);
			continue;
		}
		else
		{
			use1.money -= msg1.use.money;
			msgsnd(msgid2,&msg1,sizeof(Msg)-4,0);
		}

				
		struct Msg msg = {};
		msgrcv(msgid1,&msg,sizeof(Msg),10,0);
		struct User use;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		//如果账户不存在归还转账金额
		if(access(filename,F_OK) == -1)
		{
			msg.use.card_id = -1;
            use1.money += msg1.use.money;
            lseek(fd1,0,SEEK_SET);	
           	write(fd1,&use1,sizeof(User));	    
			close(fd1);            
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
            continue;
        }
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("转账失败");
			return -1;
		}
		if(read(fd,&use,sizeof(User)) < 0) return -1;
		use.money += msg.use.money;
		printf("%.2lf",use.money);
	   	lseek(fd,0,SEEK_SET);
	   	write(fd,&use,sizeof(User));
		close(fd);
		msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		lseek(fd1,0,SEEK_SET);	
        write(fd1,&use1,sizeof(User));	    
		close(fd1);	
	}	
}

unlock.c

//服务端解锁
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <fcntl.h>
#include "struct.h"

static int msgid1;
static int msgid2;

int main(void)
{	//创建消息队列
	msgid1 = msgget(key1,IPC_CREAT|0644);
	if(0 > msgid1)
	{
		perror("msgget");
		return -1;
	}
	msgid2 = msgget(key2,IPC_CREAT|0644);
	if(0 > msgid2)
	{
		perror("msgget");
		return -1;
	}
	while(1)
	{
		struct Msg msg={};
		msgrcv(msgid1,&msg,sizeof(Msg),9,0);
		struct User use;
		char filename[100] = {".dat"};
		sprintf(filename,"/home/zhizhen/学习课程/project/test/ATM/data/%d.dat",msg.use.card_id);
		if(access(filename,F_OK) == -1)
		{
			msg.use.card_id = -1;
            msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
            continue;
        }
		int fd = open(filename,O_RDWR,00644);
		if(fd == -1)
		{
			perror("解锁失败");
			return -1;
		}
		if(read(fd,&use,sizeof(User)) < 0) return -1;
		//该卡号锁定
		if(use.lock = 1 && use.id == msg.use.id)
		{
			use.lock = 0;
			use.cnt = 3;
	    	lseek(fd,0,SEEK_SET);
	   		write(fd,&use,sizeof(User));
			close(fd);
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		//该卡号未锁定
		else if(use.lock = 0 && use.id == msg.use.id)
		{
			msg.use.lock = -1;
			lseek(fd,0,SEEK_SET);
			close(fd);
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
		//卡号身份证不对应
		else
		{
			msg.use.card_id = -1;
			msg.use.id = -1;
			lseek(fd,0,SEEK_SET);
			close(fd);
			msgsnd(msgid2,&msg,sizeof(Msg)-4,0);
		}
	}
}
  • 一些其他定义,工具文件
    tools.h
#include "tools.h"

//清屏
void clear_scr(void)
{
	system("clear");
}

//清理输入缓冲区
void clear_stdin(void)
{
	stdin->_IO_read_ptr = stdin->_IO_read_end;
}

//获取字符串
char* get_str(char* str,uint8_t size)
{
	clear_stdin();

	fgets(str,size,stdin);
	uint8_t len = strlen(str);

	if(str[len-1] == '\n') 
	{
		str[len-1] = '\0';
	}

	clear_stdin();
}

//获取密码
char* get_pd(char* pd,uint8_t size)
{
	clear_stdin();

	uint8_t index = 0;
	while(index < size-1)
	{
		uint8_t val = get_keyboard();
		if(KEY_ENTER == val)
		{
			break;
		}
		else if(KEY_BACKSPACE == val)
		{
			if(index > 0)
			{
				printf("\b \b");
				index--;
			}
			continue;
		}
		pd[index++] = val;
		printf("*");
	}

	clear_stdin();	
	pd[index] = '\0';
	printf("\n");
	return pd;
}

//获取指令
char get_cmd(char start,char end)
{
	clear_stdin();

	printf("请输入指令:");
	while(1)
	{
		uint8_t val = get_keyboard();
		if(val >= start && val <= end)
		{
			printf("%c\n",val);
			return val;
		}
	}
}

//输入任意键继续
void anykey_continue(void)
{
	printf("请输入任意键继续...");
	get_keyboard();
	printf("\n");
}

//显示提示信息
void show_msg(char* msg,uint8_t sec)
{
	printf("\33[;34m");
	printf("*** %s *** \n",msg);
	sleep(sec);
	printf("\33[0m");
}

void display(void)
{
	clear_scr();
	puts("******************");
	puts("1、存款");
	puts("2、取款");
	puts("3、查询");
	puts("4、转账");
	puts("5、修改密码");
	puts("6、退出");
	puts("******************");
}

void show(void)
{
	clear_scr();
	puts("***欢迎使用简易ATM机***");
	puts("   1、开户");
	puts("   2、登录");
	puts("   3、销户");
	puts("   4、解锁");
	puts("   5、退出");
	puts("*********************");
}

tools.h

#ifndef TOOLS_H
#define TOOLS_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <stdint.h>
#include <get_keyboard.h>

//清屏
void clear_scr(void);

//清理输入缓冲区
void clear_stdin(void);

//获取字符串
char* get_str(char* str,uint8_t size);

//获取密码
char* get_pd(char* pd,uint8_t size);

//获取指令
char get_cmd(char start,char end);

//输入任意键继续
void anykey_continue(void);

//显示提示信息
void show_msg(char* msg,uint8_t sec);

void display(void);

void show(void);

#endif//TOOLS_H

struct.h

#ifndef STRUCT_H
#define STRUCT_H

#define key1 987654
#define key2 234567

typedef struct User
{
	char name[10]; 	//姓名
	int card_id;	//卡号
	long long id;	//身份证
	char pass[8];	//密码
	double money;	//金额
	int cnt;		//输密码次数
	int lock;		//卡号是否锁定
}User;

typedef struct Msg
{
	long type;
	User use;
}Msg;

#endif //STRUCT_H

Makefile

all:
	gcc -std=gnu99 -c client.c
	gcc -std=gnu99 -c tools.c
	gcc -std=gnu99 -c cfunc.c
	gcc  client.o tools.o cfunc.o -o c
	gcc open.c -o open
	gcc save.c -o save
	gcc extract.c -o extract
	gcc inquiry.c -o inquiry
	gcc transfer.c -o transfer
	gcc destory.c -o destory
	gcc entry.c -o entry
	gcc changepass.c -o changepass
	gcc unlock.c -o unlock
	gcc -std=gnu99 server.c -o server
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值