直接先上图:

项目需求:

主要分为两人大模块:

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

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

然后运行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" static int msgid_ctos;
static int msgid_stoc;
static pid_t sub_pid[]; void sigint(int sig)
{
msgctl(msgid_ctos,IPC_RMID,NULL);
msgctl(msgid_stoc,IPC_RMID,NULL); int i;
for(i=; i<; i++)
{
kill(sub_pid[i],SIGKILL);
}
} int main()
{
signal(SIGINT,sigint); msgctl(msgid_ctos,IPC_RMID,NULL);
msgctl(msgid_stoc,IPC_RMID,NULL); msgid_ctos = msgget(ftok(".",),IPC_CREAT|IPC_EXCL|);
msgid_stoc = msgget(ftok(".",),IPC_CREAT|IPC_EXCL|); sub_pid[] = vfork();
if( == sub_pid[])
{
execl("login","login",NULL);
printf("登陆子进程创建成功...\n");
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("open","open",NULL);
printf("开户子进程创建成功...\n");
}
sub_pid[] = vfork();
if( == sub_pid[])
{
execl("save","save",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("take","take",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("transf","transf",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("select","select",NULL);
} //login open save take transf select change destory unlock sub_pid[] = vfork();
if( == sub_pid[])
{
execl("change","change",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("destory","destory",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("unlock","unlock",NULL);
} //pause();
while(- != wait(NULL));
}
 #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" static int msgid_ctos;
static int msgid_stoc;
static pid_t sub_pid[]; void sigint(int sig)
{
msgctl(msgid_ctos,IPC_RMID,NULL);
msgctl(msgid_stoc,IPC_RMID,NULL); int i;
for(i=; i<; i++)
{
kill(sub_pid[i],SIGKILL);
}
} int main()
{
signal(SIGINT,sigint); msgctl(msgid_ctos,IPC_RMID,NULL);
msgctl(msgid_stoc,IPC_RMID,NULL); msgid_ctos = msgget(ftok(".",),IPC_CREAT|IPC_EXCL|);
msgid_stoc = msgget(ftok(".",),IPC_CREAT|IPC_EXCL|); sub_pid[] = vfork();
if( == sub_pid[])
{
execl("login","login",NULL);
printf("登陆子进程创建成功...\n");
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("open","open",NULL);
printf("开户子进程创建成功...\n");
}
sub_pid[] = vfork();
if( == sub_pid[])
{
execl("save","save",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("take","take",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("transf","transf",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("select","select",NULL);
} //login open save take transf select change destory unlock sub_pid[] = vfork();
if( == sub_pid[])
{
execl("change","change",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("destory","destory",NULL);
} sub_pid[] = vfork();
if( == sub_pid[])
{
execl("unlock","unlock",NULL);
} //pause();
while(- != 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 = ;
static int lock = ; 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(".",),);
if( > msgid_ctos)
{
perror("msgget");
return -;
}
msgid_stoc = msgget(ftok(".",),);
if( > msgid_stoc)
{
perror("msgget");
return -;
}
return ;
} void login()//
{
if(lock >= )
{
printf("您已被锁定,请解锁\n");
getchar();
return;
}
Account acc = {};
Msg msg = {};
printf("请输入帐号:");
scanf("%ld",&acc.user);
getchar();
printf("请输入密码:");
get_str(acc.pw,);
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,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()//
{ Account acc = {};
Msg msg = {};
printf("请输入姓名:");
get_str(acc.name,);
printf("请输入身份证:");
get_str(acc.id,);
printf("请输入密码:");
get_str(acc.pw,);
msg.acc = acc;
//printf("msg:%s\n",msg.acc.name);
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
printf("msg2:%s,acc:%s\n",msg2.acc.name,acc.name);
if(strcmp(acc.name,msg2.acc.name) == )
{
//printf("%s\n",msg2.acc.name);
//printf("%s\n",msg2.acc.id);
printf("帐号:%ld,开户成功\n",msg2.acc.user);
}
else
{
printf("开户失败\n");
}
getch();
} void save()//
{
Account acc = {};
Msg msg = {};
//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),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.acc.user == online)
{
printf("存钱成功\n");
}
else
{
printf("存钱失败\n");
}
getch();
} void take()//
{
Account acc = {};
Msg msg = {};
printf("请输入取款金额:");
scanf("%lf",&acc.money);
getchar();
acc.user = online;
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.acc.user == online)
{
printf("取钱成功\n");
}
else if(msg2.acc.user == online + )
{
printf("余额不足,请充值\n");
}
else
{
printf("取钱失败\n");
}
getch();
}
void transf()//
{
Account acc = {};
Msg msg = {};
printf("请输入转帐金额:");
scanf("%lf",&acc.money);
getchar();
acc.user = online;
msg.acc = acc;
msg.flag = ;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.flag == )
{
printf("请输入要转帐的帐号:");
scanf("%ld",&acc.user);
getchar();
msg.acc = acc;
msg.flag = ;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); // 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR); if(msg2.flag == )
{
printf("转帐成功\n");
}
else
{
printf("转帐失败\n");
} }
else
{
printf("余额不足,请充值\n");
}
getch();
}
void select_money()//
{
Account acc = {};
Msg msg = {};
acc.user = online;
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.acc.user == online)
{
printf("余额:%.2lf\n",msg2.acc.money);
}
else
{
printf("查询失败\n");
}
getch();
}
void change_pw()//
{
Account acc = {};
Msg msg = {};
printf("请输入新密码:");
get_str(acc.pw,);
acc.user = online;
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.acc.user == online)
{
printf("改密成功\n");
}
else
{
printf("改密失败\n");
}
getch();
} void destory()//
{
Account acc = {};
Msg msg = {};
printf("请输入销户帐号:");
scanf("%ld",&acc.user);
getchar();
printf("请输入姓名:");
get_str(acc.name,);
printf("请输入身份证:");
get_str(acc.id,);
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,MSG_NOERROR);
if(msg2.acc.user == )
{
printf("销户成功\n");
}
else if(msg2.acc.user == )
{
printf("相关信息错误\n");
}
else if(msg2.acc.user == )
{
printf("帐号不存在\n");
}
getch();
} void unlock()//
{
if(lock < )
{
printf("您没有被锁定,sorry\n");
getchar();
return;
}
Account acc = {};
Msg msg = {};
printf("请输入帐号:");
scanf("%ld",&acc.user);
getchar();
printf("请输入姓名:");
get_str(acc.name,);
printf("请输入身份证:");
get_str(acc.id,);
msg.acc = acc;
msgsnd(msgid_ctos,&msg,sizeof(Msg)-sizeof(msg.type),); //printf("消息已发送到队列\n"); Msg msg2 = {};
// 接收消息
msgrcv(msgid_stoc,&msg2,sizeof(Msg),,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 = ;
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()
{
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('',''))
{
case '':save(); break;
case '':take(); break;
case '':transf(); break;
case '':select_money(); break;
case '':change_pw();break;
case '':return;
}
}
} void menu(void)
{
while()
{
system("clear");
printf("--- 银行 ---\n");
printf("1、 开户\n");
printf("2、 销户\n");
printf("3、 登陆\n");
printf("4、 解锁\n");
printf("0、 退出\n");
switch(get_cmd('',''))
{
case '':open_acc(); break;
case '':destory(); break;
case '':login(); break;
case '':unlock(); break;
case '':return;
}
}
}

linux 下用C实现 ATM 自动取款机功能 (进程间通信)的更多相关文章

  1. 语言模拟ATM自动取款机系统

    C语言实验报告       题目名称:C语言模拟ATM自动取款机系统 C语言模拟实现ATM自动取款机功能:输入密码,余额查询,取款,存款,转账,修改密码,退出功能: 代码实现的功能: 账号及密码输入: ...

  2. C#实现ATM自动取款机

    本篇用C#实现ATM自动取款机的一些功能.面临的第一个问题是:如何把与自动取款机相关的有形的.无形的方面抽象出来.大致如下: (1)关于用户帐号的类:Account(2)关于银行数据库的类:BankD ...

  3. [转] 关于linux下通过shell命令(自动)修改用户密码

    关于linux下通过shell命令(自动)修改用户密码 2012-04-23 18:47:39 分类: 原文地址:关于linux下(自动)修改用户密码 作者:ubuntuer 本文章总结了如何手动.自 ...

  4. Linux下实现mysql数据库每天自动备份

    Linux下实现mysql数据库每天自动备份 1.基本操作步骤 a.创建备份目录 mkdir -m 777 /home/wwwroot/backup b.创建备份脚本sh vim /home/wwwr ...

  5. Linux下搭建SVN服务器及自动更新项目文件到web目录(www)的方法

    首先搭建SVN服务器 1,安装SVN服务端 直接用apt-get或yum安装subversion即可(当然也可以自己去官方下载安装) sudo apt-get install subversion   ...

  6. Linux下C语言实现ATM取款机,消息队列版本

    链接:https://pan.baidu.com/s/1oBavXBuZul7ZAEBL1eYfRA 提取码:ffhg Mybank ATM取款机实验,消息队列实现本实验用的是Centos71.在服务 ...

  7. Linux下svn提交文件后自动同步更新到网站目录

    有时,对于多文件需要上传到服务器的时候将会很麻烦,但是如果使用svn的钩子脚本就容易实现本地提交svn后,自动同步代码文件到远程服务器的网站目录下,而不必手动上传了. 首先,在网站目录下checkou ...

  8. Linux 下通过脚本实现远程自动备份

    考虑到在本机上备份数据,一旦该机器硬盘出现故障,数据无法取出.远程手动备份数据费时费力且不及时.最好的方法就是通过脚本实现远程自动互备.但远程无论是通过SSH登陆,还是通过scp拷贝文件都需要输入密码 ...

  9. Linux下SVN+多个Tomcat自动部署

    项目中都是jsp开发,所以用到Tomcat. 在我文章中也写过多个Tomcat 的部署,具体可以参考:http://www.cnblogs.com/magmell/p/7045193.html SVN ...

随机推荐

  1. cube.js 学习(十一)cube + gitbase 分析git 代码

    这个是一个简单的demo,使用gitbase+cube 分析git 仓库代码 需求 我们平时使用的gitlab,或者gogs 等git 仓库管理工具,有自己的管理强项,但是对于分析上可能就不是那么强大 ...

  2. 计蒜之道 百度AI小课堂-上升子序列

    计蒜之道 百度AI小课堂-上升子序列 题目描述 给一个长度为 \(n\) 的数组 \(a\) .试将其划分为两个严格上升子序列,并使其长度差最小. 输入格式 输入包含多组数据. 数据的第一行为一个正整 ...

  3. [PA2012]Dwa torty

    [PA2012]Dwa torty 题目大意: 给定两个排列\(A_{1\sim n},B_{1\sim n}\),你需要将两个排列用最少的次数消除. 消除只能从头消除,一次消除可以从两个排列的头部取 ...

  4. P3746 【[六省联考2017]组合数问题】

    题目是要我们求出如下柿子: \[\sum_{i=0}^{n}C_{nk}^{ik+r}\] 考虑k和r非常小,我们能不能从这里切入呢? 如果你注意到,所有组合数上方的数\(\%k==r\),那么是不是 ...

  5. C博客作业00——我的第一篇博客

    1.你对网络专业或计算机专业了解是怎样? 初看字眼,便觉得是理工性很强的专业,所以需要较强的开拓思维,创新精神,探索未知事物的勇气,才能掌握并且熟练应用相关知识.计算机类专业都需要学习计算机语言,而计 ...

  6. GDOI2018 小学生图论题 [NTT]

    并没有传送门qwq 思路 首先要知道一个结论(或者说是一个套路):一个竞赛图缩点之后必定是一条链. 那么强联通分量的个数,就是这条链的边数+1. 考虑一条边什么时候会出现:当且仅当点集可以被分成\(S ...

  7. SpringBoot聚合项目打包

    1.打包遇到的问题: 子模块打包时,每次打包出来的jar都只有3k左右,没办法运行,目测应该是依赖的jar没有打包进来! 2.解决办法: 2.1.主项目的pom.xml里面不需要打包配置 2.2.在需 ...

  8. 【大数据】安装关系型数据库MySQL 安装大数据处理框架Hadoop

    作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 1.安装Mysql 使用命令  sudo apt-get ins ...

  9. NoSql数据库Redis系列(5)——Redis主从复制

    前面介绍Redis,我们都在一台服务器上进行操作的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都 ...

  10. 正则表达式在线分析 regex online analyzer

    https://regexper.com/#%2F%5B0-9%5D%5Cs%5B0-9%5D%2F https://regexper.com/ http://regexone.com/lesson/ ...