网络版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 !\n");
 20     printf("---------------------\n");
 21     printf("    [1]开户        \n");
 22     printf("    [2]登录        \n");
 23     printf("    [3]解锁        \n");
 24     printf("    [4]销户        \n");
 25     printf("    [5]退出        \n");
 26     printf("---------------------\n");
 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\n",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*****\n",msg.acc.account,msg.acc.money);
 50     sleep(2);
 51 }
 52 //显示登陆后的功能界面
 53 void func_menu(void)
 54 {
 55     printf("Welcome to Online Bank !\n");
 56     printf("---------------------\n");
 57     printf("    [1]存款        \n");
 58     printf("    [2]取款        \n");
 59     printf("    [3]转账        \n");
 60     printf("    [4]查询        \n");
 61     printf("    [5]修密        \n");
 62     printf("    [6]退出        \n");
 63     printf("---------------------\n");
 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("退出成功!\n");
 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("存款成功!\n");
 91     printf("*****您的id是%d,账号内的余额为%f*****\n",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("取款失败!\n");
110         sleep(2);
111     }
112     else
113     {
114         printf("取款成功!\n");
115         printf("*****您的id是%d,账号内的余额为%f*****\n",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("您的余额不足!\n");sleep(2);break;
140         case -2:printf("转账对象不存在!\n");sleep(2);break;
141         case 0:    printf("转账成功!\n");
142                 printf("*****您的id是%d,账号内的余额为%f*****\n",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用户您好!\n",msg.acc.name);
158     printf("账号ID:%d\n",msg.acc.account);
159     printf("身份证号:%s\n",msg.acc.idcard);
160     printf("账号余额:%f\n",msg.acc.money);
161     printf("*****按任意键返回*****\n");
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("密码格式不符!\n");
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("修改失败!\n");
189             sleep(2);
190         }
191         else
192         {
193             printf("修改成功!\n");
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] = '\0';
226     int i = 0;
227     char index[6] = "-\\|/\0";
228     while (i <= 99)
229     {
230         buf[i+1] = '>';
231         printf("%s[%d%%][%c]\r",buf,i,index[i%4]);
232         fflush(stdout);//刷新缓冲区
233         usleep(50000);
234         i++;
235     }
236  
237     printf("\n");
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\n",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("该账号已在其他客户端登录!\n");
267             sleep(2);
268             return;
269         }
270     }
271     else if(3 <= msg.acc.flag)
272     {
273         printf("账号已被锁定!请先前往解锁!\n");
274         sleep(2);
275         return;
276     }
277     else
278     {
279         printf("登录失败!用户或密码错误!\n");
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("输入信息不正确或该账户不需要解锁!\n");
304         sleep(2);
305         return;
306     }
307     printf("解锁成功!\n");
308     printf("*****您的id是%d,新密码为%s*****\n",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("销户成功!\n");
331         sleep(2);
332     }
333     else
334     {
335         printf("销户失败!\n");
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("\b \b");
32             }
33             else
34             {
35                 i--;
36             }
37         }
38         else if(pw[i] == 10)
39         {
40             pw[i]='\0';
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 

posted on 2019-03-08 19:34  FutureNow  阅读(329)  评论(0编辑  收藏  举报