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