zoukankan      html  css  js  c++  java
  • 网络版ATM项目的实现——客户端

    网络版的ATM实现思路

    客户端

      1 #include "customer.h"
      2 
      3 static int sockfd;
      4 
      5 /*int create_msg_queue_c(int key)
      6 {
      7     //创建消息队列
      8     int msgid = msgget(key,IPC_CREAT|0644);
      9     if(0 > msgid)
     10     {
     11         perror("msgget");
     12         return -1;
     13     }
     14     return msgid;
     15 }*/
     16 
     17 void show_menu(void)
     18 {
     19     printf("Welcome to Online Bank !
    ");
     20     printf("---------------------
    ");
     21     printf("    [1]开户        
    ");
     22     printf("    [2]登录        
    ");
     23     printf("    [3]解锁        
    ");
     24     printf("    [4]销户        
    ");
     25     printf("    [5]退出        
    ");
     26     printf("---------------------
    ");
     27 }
     28 //开户界面
     29 void open_menu(void)
     30 {
     31     
     32     Msg msg = {99};
     33     //得到基本信息
     34     printf("请输入姓名:");
     35     gets(msg.acc.name);
     36     printf("请输入身份证号:");
     37     gets(msg.acc.idcard);
     38     printf("请输入预存金额:");
     39     scanf("%f",&msg.acc.money);
     40     //清空缓冲区
     41     stdin->_IO_read_ptr = stdin->_IO_read_end;
     42     strcpy(msg.acc.password,"123456");
     43     printf("%d
    ",msg.acc.account);
     44     //将获得的基本信息发送到服务端
     45     send(sockfd,&msg,sizeof(Msg),0);
     46     //接收服务端传回的信息(账号id)
     47     recv(sockfd,&msg,sizeof(Msg),0);
     48     //perror("msgrcv");
     49     printf("*****您的id是%d,初始密码为123456,账号内的余额为%f*****
    ",msg.acc.account,msg.acc.money);
     50     sleep(2);
     51 }
     52 //显示登陆后的功能界面
     53 void func_menu(void)
     54 {
     55     printf("Welcome to Online Bank !
    ");
     56     printf("---------------------
    ");
     57     printf("    [1]存款        
    ");
     58     printf("    [2]取款        
    ");
     59     printf("    [3]转账        
    ");
     60     printf("    [4]查询        
    ");
     61     printf("    [5]修密        
    ");
     62     printf("    [6]退出        
    ");
     63     printf("---------------------
    ");
     64 }
     65 //退出登录
     66 void logout(int id)
     67 {
     68     
     69     Msg msg = {50};
     70     msg.acc.account = id;
     71     send(sockfd,&msg,sizeof(Msg),0);
     72     //接收服务端传回的信息(账号id)
     73     recv(sockfd,&msg,sizeof(Msg),0);
     74     printf("退出成功!
    ");
     75     sleep(2);
     76 }
     77 //存钱界面
     78 void save(int id)
     79 {
     80     Msg msg = {5};
     81     msg.acc.account = id;
     82     printf("请输入要存的金额:");
     83     scanf("%f",&msg.acc.money);
     84     //清空缓冲区
     85     stdin->_IO_read_ptr = stdin->_IO_read_end;
     86     //将获得的基本信息发送到服务端
     87     send(sockfd,&msg,sizeof(Msg),0);
     88     //接收服务端传回的信息(账号id)
     89     recv(sockfd,&msg,sizeof(Msg),0);
     90     printf("存款成功!
    ");
     91     printf("*****您的id是%d,账号内的余额为%f*****
    ",msg.acc.account,msg.acc.money);
     92     sleep(2);
     93 }
     94 //取款界面
     95 void take(int id)
     96 {
     97     Msg msg = {6};
     98     msg.acc.account = id;
     99     printf("请输入要取的金额:");
    100     scanf("%f",&msg.acc.money);
    101     //清空缓冲区
    102     stdin->_IO_read_ptr = stdin->_IO_read_end;
    103     //将获得的基本信息发送到服务端
    104     send(sockfd,&msg,sizeof(Msg),0);
    105     //接收服务端传回的信息(账号id)
    106     recv(sockfd,&msg,sizeof(Msg),0);
    107     if(-1 == msg.acc.flag)
    108     {
    109         printf("取款失败!
    ");
    110         sleep(2);
    111     }
    112     else
    113     {
    114         printf("取款成功!
    ");
    115         printf("*****您的id是%d,账号内的余额为%f*****
    ",msg.acc.account,msg.acc.money);
    116         sleep(2);
    117     }
    118 }
    119 //转账界面
    120 void trans(int id)
    121 {
    122     Msg msg1 = {7};
    123     //Msg msg2 = {17};
    124     msg1.acc.account = id;
    125     printf("请输入转账对象的id:");
    126     scanf("%d",&msg1.acc.target);
    127     //清空缓冲区
    128     stdin->_IO_read_ptr = stdin->_IO_read_end;
    129     printf("请输入要转账的金额:");
    130     scanf("%f",&msg1.acc.money);
    131     //清空缓冲区
    132     stdin->_IO_read_ptr = stdin->_IO_read_end;
    133     //将获得的基本信息发送到服务端
    134     send(sockfd,&msg1,sizeof(Msg),0);
    135     //接收服务端传回的信息(账号id)
    136     recv(sockfd,&msg1,sizeof(Msg),0);
    137     switch(msg1.acc.flag)
    138     {
    139         case -1:printf("您的余额不足!
    ");sleep(2);break;
    140         case -2:printf("转账对象不存在!
    ");sleep(2);break;
    141         case 0:    printf("转账成功!
    ");
    142                 printf("*****您的id是%d,账号内的余额为%f*****
    ",msg1.acc.account,msg1.acc.money);
    143                 sleep(2);break;
    144     }
    145 }
    146 
    147 //查询界面
    148 void show(int id)
    149 {
    150     system("clear");
    151     Msg msg = {8};
    152     msg.acc.account = id;
    153     //将获得的基本信息发送到服务端
    154     send(sockfd,&msg,sizeof(Msg),0);
    155     //接收服务端传回的信息(账号id)
    156     recv(sockfd,&msg,sizeof(Msg),0);
    157     printf("%s用户您好!
    ",msg.acc.name);
    158     printf("账号ID:%d
    ",msg.acc.account);
    159     printf("身份证号:%s
    ",msg.acc.idcard);
    160     printf("账号余额:%f
    ",msg.acc.money);
    161     printf("*****按任意键返回*****
    ");
    162     getchar();    
    163 }
    164 
    165 //修改密码界面
    166 void change(int id)
    167 {
    168     Msg msg = {9};
    169     msg.acc.account = id;
    170     printf("请输入您的身份账号以用于验证用户信息:");
    171     gets(msg.acc.idcard);
    172     printf("请输入新密码(6位):");
    173     put_pw(msg.acc.password);
    174     if(6 != strlen(msg.acc.password))
    175     {
    176         printf("密码格式不符!
    ");
    177         sleep(2);
    178         return;
    179     }
    180     else
    181     {
    182         //将获得的基本信息发送到服务端
    183         send(sockfd,&msg,sizeof(Msg),0);
    184         //接收服务端传回的信息(账号id)
    185         recv(sockfd,&msg,sizeof(Msg),0);
    186         if(-1 == msg.acc.flag)
    187         {
    188             printf("修改失败!
    ");
    189             sleep(2);
    190         }
    191         else
    192         {
    193             printf("修改成功!
    ");
    194             sleep(2);
    195         }
    196     }
    197 }
    198 
    199 //副主界面
    200 void ano_main(int id)
    201 {
    202     while(1)
    203     {
    204         system("clear");
    205         func_menu();
    206         switch(getch())
    207         {
    208             case 49:save(id);break;
    209             case 50:take(id);break;
    210             case 51:trans(id);break;
    211             case 52:show(id);break;
    212             case 53:change(id);break;
    213             case 54:logout(id);return;
    214         }
    215     }
    216 }
    217 //加载界面
    218 void loading(void)
    219 {
    220     //system("clear");
    221     char buf[103] = {};
    222     memset(buf, ' ', sizeof(buf));
    223     buf[0] = '[';
    224     buf[101] = ']';
    225     buf[102] = '';
    226     int i = 0;
    227     char index[6] = "-\|/";
    228     while (i <= 99)
    229     {
    230         buf[i+1] = '>';
    231         printf("%s[%d%%][%c]
    ",buf,i,index[i%4]);
    232         fflush(stdout);//刷新缓冲区
    233         usleep(50000);
    234         i++;
    235     }
    236  
    237     printf("
    ");
    238 }
    239 //登录界面
    240 void login_menu(void)
    241 {
    242     Msg msg = {2};
    243     msg.acc.flag = -1;
    244     //获取账号密码
    245     printf("请输入账号:");
    246     scanf("%d",&msg.acc.account);
    247     //清空缓冲区
    248     stdin->_IO_read_ptr = stdin->_IO_read_end;
    249     printf("请输入密码:");
    250     put_pw(msg.acc.password);
    251     //将获得的基本信息发送到服务端
    252     send(sockfd,&msg,sizeof(Msg),0);
    253     //接收服务端传回的信息(账号id)
    254     recv(sockfd,&msg,sizeof(Msg),0);
    255     printf("%d
    ",msg.acc.flag);
    256     //根据判断结果跳转界面
    257     if(0 == msg.acc.flag)
    258     {
    259         if(0 == msg.acc.sp)
    260         {
    261             loading();
    262             ano_main(msg.acc.account);
    263         }
    264         else
    265         {
    266             printf("该账号已在其他客户端登录!
    ");
    267             sleep(2);
    268             return;
    269         }
    270     }
    271     else if(3 <= msg.acc.flag)
    272     {
    273         printf("账号已被锁定!请先前往解锁!
    ");
    274         sleep(2);
    275         return;
    276     }
    277     else
    278     {
    279         printf("登录失败!用户或密码错误!
    ");
    280         sleep(2);
    281         return;
    282     }    
    283 }
    284 
    285 //解锁界面
    286 void unlock_menu(void)
    287 {
    288     Msg msg = {3};
    289     printf("请输入要解锁的账号:");
    290     scanf("%d",&msg.acc.account);
    291     //清空缓冲区
    292     stdin->_IO_read_ptr = stdin->_IO_read_end;
    293     printf("请输入身份证号:");
    294     gets(msg.acc.idcard);
    295     printf("请输入新密码:");
    296     put_pw(msg.acc.password);
    297     //将获得的基本信息发送到服务端
    298     send(sockfd,&msg,sizeof(Msg),0);
    299     //接收服务端传回的信息(账号id)
    300     recv(sockfd,&msg,sizeof(Msg),0);
    301     if(-1 == msg.acc.flag)
    302     {    
    303         printf("输入信息不正确或该账户不需要解锁!
    ");
    304         sleep(2);
    305         return;
    306     }
    307     printf("解锁成功!
    ");
    308     printf("*****您的id是%d,新密码为%s*****
    ",msg.acc.account,msg.acc.password);
    309     sleep(2);
    310     return;    
    311 }
    312 
    313 //销户界面
    314 void delete_menu(void)
    315 {
    316     Msg msg = {4};
    317     //获取账号密码
    318     printf("请输入账号:");
    319     scanf("%d",&msg.acc.account);
    320     //清空缓冲区
    321     stdin->_IO_read_ptr = stdin->_IO_read_end;
    322     printf("请输入密码:");
    323     put_pw(msg.acc.password);
    324     //将获得的基本信息发送到服务端
    325     send(sockfd,&msg,sizeof(Msg),0);
    326     //接收服务端传回的信息(账号id)
    327     recv(sockfd,&msg,sizeof(Msg),0);
    328     if(-2 == msg.acc.flag)
    329     {
    330         printf("销户成功!
    ");
    331         sleep(2);
    332     }
    333     else
    334     {
    335         printf("销户失败!
    ");
    336         sleep(2);
    337     }
    338     return;
    339 }
    340 int main()
    341 {
    342     // 创建socket对象
    343     sockfd = socket(AF_INET,SOCK_STREAM,0);
    344     if(0 > sockfd)
    345     {
    346         perror("socket");
    347         return -1;
    348     }
    349     // 准备通信地址
    350     struct sockaddr_in addr = {};
    351     addr.sin_family = AF_INET;
    352     addr.sin_port = htons(1904);
    353     addr.sin_addr.s_addr = inet_addr("192.168.1.110");
    354     // 连接
    355     if(0 > connect(sockfd,(struct sockaddr*)&addr,sizeof(addr)))
    356     {
    357         perror("connect");
    358         return -1;
    359     }
    360     
    361     while(1)
    362     {
    363         system("clear");
    364         show_menu();
    365         switch(getch())
    366         {
    367             case 49:open_menu();break;
    368             case 50:login_menu();break;
    369             //case 51:unlock_menu();break;
    370             //case 52:delete_menu();break;
    371             case 53:return 0;
    372         }
    373     }
    374 }

    使用的工具函数

     1 #include "customer.h"
     2 
     3 //创建消息队列
     4 int create_msg_queue(int keynum)
     5 {
     6     //获取ipc键值
     7     key_t key = ftok("~",keynum);
     8     //创建消息队列
     9     int msgid = msgget(key,IPC_CREAT|0644);
    10     if(0 > msgid)
    11     {
    12         perror("msgget");
    13         return -1;
    14     }
    15     
    16     return msgid;
    17 }
    18 
    19 //隐藏密码输入
    20 char* put_pw(char* pw)
    21 {
    22     for(int i=0; i<20; i++)
    23     {
    24         stdin->_IO_read_ptr=stdin->_IO_read_end;
    25         pw[i]=getch();
    26         if(pw[i] == 127)
    27         {
    28             if(i>0)
    29             {
    30                 i -= 2;
    31                 printf(" ");
    32             }
    33             else
    34             {
    35                 i--;
    36             }
    37         }
    38         else if(pw[i] == 10)
    39         {
    40             pw[i]='';
    41             break;
    42         }
    43         else
    44         {
    45             putchar('*');
    46         }
    47     }
    48     return pw;
    49 }

    定义的头文件

     1 #ifndef CUSTOMER_H
     2 #define CUSTOMER_H
     3 
     4 #include <stdio.h>
     5 #include <sys/types.h>
     6 #include <sys/ipc.h>
     7 #include <sys/msg.h>
     8 #include <string.h>
     9 #include <unistd.h>
    10 #include <stdlib.h>
    11 #include <fcntl.h>
    12 #include <sys/wait.h>
    13 #include <getch.h>
    14 #include <stdbool.h>
    15 #include <sys/socket.h>
    16 #include <netinet/in.h>
    17 #include <arpa/inet.h>
    18 #include <pthread.h>
    19 #include <semaphore.h>
    20 #include <signal.h>
    21 
    22 #define key1 123456
    23 #define key2 654321
    24 typedef struct Account
    25 {
    26     int account;
    27     int target;
    28     char name[20];
    29     char password[10];
    30     char idcard[18];
    31     float money;
    32     int flag;
    33     int sp;
    34 }Account;
    35 typedef struct Msg
    36 {
    37     long type;
    38     Account acc;
    39 }Msg;
    40 
    41 int create_msg_queue(int keynum);
    42 char* put_pw(char* pw);
    43 
    44 #endif

    Makefile

     1 all: 2 gcc -std=gnu99 -c customer.c 3 gcc -std=gnu99 -c tools.c 4 gcc customer.o tools.o -o customer -lpthread 

  • 相关阅读:
    AWS re:Invent 2019 召开 | 云原生生态周报 Vol. 30
    更强、更稳、更高效:解读 etcd 技术升级的三驾马车
    Service Mesh 是新瓶装旧酒吗?
    从零开始入门 K8s | 深入剖析 Linux 容器
    阿里云上万个 Kubernetes 集群大规模管理实践
    CNCF 官方大使张磊:什么是云原生?
    函数计算自动化运维实战 3 -- 事件触发自动创建快照
    函数计算自动化运维实战 2 -- 事件触发 eip 自动转移
    函数计算自动化运维实战1 -- 定时任务
    273. Integer to English Words
  • 原文地址:https://www.cnblogs.com/kid971220/p/10497801.html
Copyright © 2011-2022 走看看