项目需求
主要分为两人大模块:
客户端
1、进入时的功能开户、销户、登录、解锁
开户:输入姓名、身份证号、设置密码,如果开户成功,则服务器上保存一个账号信号(一个账号存一个文件,文件名建议是账号)。
销户:输入帐号、密码,服务器询问是否确认销户,如果确认则服务器删除帐号文件,并记录帐号。
登录:输入账号、密码,三次错误账号锁定。
解锁:输入账号、身份证号解锁。
2、登录成功:存钱、取钱、转账、查询、修改密码
存钱:输入存钱金额
取钱:输入取钱金额
转账:目标帐号和要转的金额
查询:不需要输入数据
修改密码:原密码和新密码
服务器
如果识别功能:根据消息的类型识别客户端请求的功能。
开启服务各项功能的子进程
各进程按照消息类型接收消息
头文件
#define key 123456
帐号结构体
{
帐号
身份证号
密码
金额
}
消息结构体
{
消息类型
帐号结构体
}
系统实现方法
系统分为客户端和服务器,客户端用于接收用户输入的信息,服务器创建多个子进程,用于实现各项功能
用户在客户端输入信息,通过进程间通信传给服务器,服务器接收后,用相应的子进程实现功能,并将实现的情况返回给客户端
码云:下载地址
代码使用:下载后解压放到linux中,打开两个终端,都进入到xxbank/server文件夹中,输入make,产生相应文件,先在一个终端中输入./server,运行服务器,在另一个终端输入./client运行客户端,然后就可以开始使用了(如果出错可能是消息队列没有清除,请清除后再运行)
功能展示
开户

销户
登录
解锁
存钱
取钱
转账
查询余额
修改密码
部分代码展示
//client.c 代码
#include <stdio.h>
#include <unistd.h>
#include <msg.h>
#include <bank.h>
#include <getch.h>
#include <string.h>
#include <stdlib.h>
#define STDIN_CLEAR stdin ->_IO_read_ptr = stdin -> _IO_read_end
//按任意按键继续
void anykey_continue(void)
{
puts("按任意按键继续...");
//防止输入缓冲区中有残留的字符,会导致getch直接返回
//因此清理输入缓冲区
STDIN_CLEAR;
getch();
}
//接受数据并去除fgets()末尾的\n
void fgets_n(char* str,int n)
{
STDIN_CLEAR;
memset(str, 0, strlen(str));
fgets(str,n,stdin);
if(str[n-1]=='\n')
{
str[n-1]='\0';
}
STDIN_CLEAR;
}
int msgid;
MsgCTOS ctos = {};
MsgSTOC stoc = {};
void menu(void)
{
puts("欢迎使用XX银行");
puts("1 开户");
puts("2 销户");
puts("3 登陆");
puts("4 解锁");
puts("0 退出");
}
void open(void)
{
ctos.type = OPEN_MSG;
printf("请输入身份证号:");
fgets_n(ctos.user.card_id,19);
printf("请输入密码(6位纯数字):");
fgets_n(ctos.user.passwd,7);
printf("msg=%d\n",msgid);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void destory(void)
{
ctos.type = DESTORY_MSG;
printf("请输入银行卡号:");
fgets_n(ctos.user.bank_id,16);
printf("请输入密码:");
fgets_n(ctos.user.passwd,7);
printf("msg=%d\n",msgid);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void login(void)
{
ctos.type = LOGIN_MSG;
printf("请输入银行卡号:");
fgets_n(ctos.user.bank_id,16);
printf("请输入密码:");
fgets_n(ctos.user.passwd,7);
printf("msg=%d\n",msgid);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
sleep(1);
}
void unlock(void)
{
ctos.type = UNLOCK_MSG;
printf("请输入银行卡号:");
fgets_n(ctos.user.bank_id,16);
printf("请输入身份证号:");
fgets_n(ctos.user.card_id,19);
printf("msg=%d\n",msgid);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
sleep(1);
}
void save(void)
{
ctos.type = SAVE_MSG;
printf("请输入存钱金额:");
scanf("%lf",&ctos.user.balance);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void take(void)
{
ctos.type = TAKE_MSG;
printf("请输入取钱金额:");
scanf("%lf",&ctos.user.balance);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void turn(void)
{
ctos.type = TURN_MSG;
printf("请输入转帐卡号:");
fgets_n(ctos.user.card_id,16);
printf("请输入转帐金额:");
scanf("%lf",&ctos.user.balance);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void query(void)
{
ctos.type = QUERY_MSG;
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void change(void)
{
ctos.type = CHANGE_MSG;
printf("请输入修改后的密码(6位纯数字):");
fgets_n(ctos.user.passwd,7);
send_msg(msgid,&ctos,sizeof(MsgCTOS));
recv_msg(msgid,&stoc,sizeof(MsgSTOC),getpid());
printf("status:%d\n%s\n",stoc.status,stoc.str);
anykey_continue();
}
void user_menu(void)
{
for(;;)
{
system("clear");
puts("用户界面");
puts("1 存钱");
puts("2 取钱");
puts("3 转帐");
puts("4 查询");
puts("5 改密");
puts("0 退出");
char cmd = getch();
switch(cmd)
{
case '1':save();break;
case '2':take();break;
case '3':turn();break;
case '4':query();break;
case '5':change();break;
case '0':return;
default:break;
}
}
}
int main()
{
msgid = get_msg(MSGKEY);
ctos.pid = getpid();
for(;;)
{
system("clear");
menu();
char cmd = getch();
switch(cmd)
{
case '1':open();break;
case '2':destory();break;
case '3':
login();
if(0 == stoc.status)
{
user_menu();
}
break;
case '4':unlock();break;
case '0':return 0;
default:break;
}
}
}