首页 > 技术文章 > 【C】——C模拟atm取款机

ngnetboy 2014-01-12 22:29 原文

  功能描述:1:开户;2:销户;3:存钱;4:取钱;5:查询;6:转账;

主要用的技术:

  一:消息队列:

    1)key_t key = ftok(".",100); //获取key

    2)msgid = msgget(key,IPC_CREATE|0666); //创建   msgid = msgget(key,0); //获取

    3)msgsnd = msgsnd = (msgid,&msg,sizeof(msg),0);  //发送

    4)msgrcv = msgrcv = (msgid,&msg,sizeof(msg),0,0); //获取

    5)msgt = msgctl(msgid,IPC_RMID,NULL);  //删除

  二:信号:

      signal(int sinno, void (*fa)(int));

  三:文件操作:

      int access(const char *filename);  //查看文件是否存在

      int open(int fd,int oflag,.../* mode_t mode*/)

      ssize_t write(int fd,void *buf,size_t nbytes);

      ssize_t read(int fd,void *buf,size_t nbytes);

思想架构:

  头文件:

    dao.h   ----> 定义文件操作的函数

    bank.h  -----> 定义宏,结构体,设置外部变量 key1 key2

  .c文件

    client.c  ---->  客户端操作  主要包括客户端的输入提示,和把数据传入服务器端

    server.c  ---->  创建消息队列,启动服务端,用vfork()创建子进程,用execl() 执行open.c 的目标文件。并且设定  SIG_INT 信号,接收此信号时就删除消息队列。

    open.c  ----->  用来接收客户端传来的消息,并对消息进行业务逻辑操作

    dao.c   ----->   dao.h中一定的函数的具体实现,供open.c 文件调用,主要是用来对文件的操作。

    bank.c  ---->  此文件主要用来对两个 key 赋值。

感觉有点类似网站建设中的三层架构。

client.c  主要用来负责用户层

open.c  主要用来负责业务逻辑层

dao.c  主要用来负责数据操作层

 

设计的技术点不多,但是确实个规范的项目。头文件和各个文件的作用值得学习。框架是老师建的,功能都是自己实现的,如有错误还望指正:

bank.h:

 1 //客户端和服务器端共用的头文件
 2 #ifndef BANK_H_
 3 #define BANK_H_
 4 //声明两个key值,用来给消息队列用,这两个key在另一个文件中定义
 5 
 6 extern const int key1;//客户端向服务器发送消息队列的键值key
 7 extern const int key2;//服务器向客户端发送的
 8 
 9 //消息类型 定义为各种宏 方便处理
10 #define M_OPEN 1//代表开户类型
11 #define M_DESTROY 2 //销户
12 #define M_SAVE 3 //存钱
13 #define M_TAKE 4 //取钱
14 #define M_QUERY 5 //查询
15 #define M_TRANSF 6 //转账
16 #define M_SUCCESS 7 //处理成功
17 #define M_FAILED 8 //处理失败
18 
19 //包含帐户信息的帐户结构体
20 struct Account{
21     int id;//帐号
22     char name[10];//用户名
23     char password[10];//密码
24     double balance;//金额
25 };
26 
27 //消息的结构体
28 struct Msg{
29     long  mtype;//消息的类型
30     struct Account acc;//帐户的信息结构体
31 };
32 #endif

dao.h:

 1 //数据对象的存储
 2 #ifndef DAO_H_
 3 #define DAO_H_
 4 #include "bank.h"
 5 //生成不重复的帐号
 6 int generator_id();
 7 //将新帐号添加到文件中,为开户服务
 8 int createUser(struct Account acc);
 9 //销户功能
10 int destroyUser(struct Account acc);
11 //存钱功能
12 int saveMoney(struct Account acc,struct Account *p);
13 //取钱功能
14 int getMoney(struct Account acc,struct Account *p);
15 //查询余额功能
16 int checkMoney(struct Account acc,struct Account *p);
17 //转账功能
18 int moveMoney(struct Account acc1,struct Account acc2,struct Account *p);
19 #endif

bank.c:

1 //对头文件中的变量进行定义
2 #include "bank.h"
3 
4 const int key1 = 0x12345678;
5 const int key2 = 0x23456789;

server.c:

 1 //ATM的服务器端
 2 #include "bank.h"
 3 #include <sys/types.h>
 4 #include <sys/ipc.h>
 5 #include <sys/msg.h>
 6 #include <stdio.h>
 7 #include <stdlib.h>
 8 #include <unistd.h>
 9 #include <signal.h>
10 
11 //首先需要创建两个全局存储消息队列的id的变量
12 static int msgid1;
13 static int msgid2;
14 //写一个函数,用来创建两个消息队列,用到msgget函数
15 void init(){
16     //msgget函数,第一个参数是键值,bank.h中有
17     //IPC_CREAT表示没有此消息队列则创建,
18     //IPC_EXCL表示如果队列存在,则提示错误
19     //0666是给此消息队列对象添加一些权限设置,类似文件系统
20     //创建消息队列1
21     msgid1 = msgget(key1,IPC_CREAT|IPC_EXCL|0666);
22     if(msgid1 == -1){
23         perror("消息队列1创建失败"),exit(-1);
24     }
25     printf("消息队列1创建成功\n");
26     //创建消息队列2
27     msgid2 = msgget(key2,IPC_CREAT|IPC_EXCL|0666);
28     if(msgid2 == -1){
29         perror("消息队列2创建失败");
30         exit(-1);
31     }
32     printf("消息队列2创建成功\n");
33 }
34 //启动服务函数,用来创建子进程来执行用户不同的选择的结果
35 void start(){
36     printf("服务器正在启动..\n");
37     sleep(2);
38     //创建子进程
39     pid_t open_pid = vfork();
40     if(open_pid == -1){
41         perror("vfork failed");
42         exit(-1);
43     }
44     else if(open_pid == 0){//进入子进程
45         //printf("in child process\n");
46         execl("./open","open",NULL);//不再和父进程共用代码段
47         exit(-1);
48     }
49     else{
50         printf("正在等待客户端选择..\n");
51         waitpid(open_pid,0,0);//阻塞,等待子进程结束
52         //printf("in parent process\n");
53     }
54 }
55 
56 void sig_exit(){
57     printf("服务器正在关闭..\n");
58     sleep(1);
59     if(msgctl(msgid1,IPC_RMID,NULL) == -1){
60         perror("消息队列1删除失败\n");
61         exit(-1);
62     }
63     else{
64         printf("消息队列1删除成功\n");
65     }
66     if(msgctl(msgid2,IPC_RMID,NULL) == -1){
67         perror("消息队列2删除失败\n");
68         exit(-1);
69     }
70     else{
71         printf("消息队列2删除成功\n");
72     }
73     printf("服务器成功关闭\n");
74     exit(0);//直接结束程序
75     
76 }
77 int main(){
78     //我们退出服务器用一个信号处理函数来实现
79     printf("退出服务器请按CTRL+C\n");//发送SIGINT信号
80     signal(SIGINT,sig_exit);//自定义信号处理函数,进行退出操作
81     //做好了善后工作,我们从头开始启动服务器
82     //创建消息队列
83     init();
84     //启动服务
85     
86     start();
87     return 0;
88 }

open.c:

  1 /*开户*/
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 #include <sys/ipc.h>
  6 #include <sys/msg.h>
  7 #include "bank.h"
  8 int main(){
  9     int msgid1 = msgget(key1,0);
 10     if(msgid1 == -1){
 11         perror("获取消息队列1失败");
 12         printf("服务器启动失败");
 13         exit(-1);
 14     }
 15     int msgid2 = msgget(key2,0);
 16     if(msgid2 == -1){
 17         perror("获取消息队列2失败");
 18         printf("服务器启动失败");
 19         exit(-1);
 20     }
 21     //获取到消息队列之后,开始接受消息
 22     while(1){
 23         struct Msg msg;//存储消息信息的结构体
 24         struct Account accMove,accResult;//存储帐户信息
 25         //首先从客户那里收取消息队列1的信息 msgrcv 函数
 26         if(msgrcv(msgid1,&msg,sizeof(msg.acc),0,0) <=0 ){
 27             break;
 28         }
 29         //如果接受到了消息,根据消息的不同类型进行不同的操作
 30         if(msg.mtype == M_OPEN){//如果类型是开户
 31             int id = generator_id();
 32             accMove = msg.acc;
 33             accMove.id = id;
 34             if(createUser(accMove)==-1){
 35                 printf("开户失败");
 36                 msg.mtype = M_FAILED;//将消息类型置成失败
 37             }
 38             else{
 39                 printf("开户成功");
 40                 msg.mtype = M_SUCCESS;
 41             }
 42             msg.acc.id = id;
 43             msgsnd(msgid2,&msg,sizeof(msg.acc),0);//将消息由消息队列2发送给客户端
 44             //执行开户的操作
 45             //给用户分配帐号,将用户信息记录在文件中。
 46         }
 47         //最后把消息发过去,这时候消息的类型应该是两种情况M_SUCESS
 48         //或者是M_FAILED 
 49         else if(msg.mtype == M_DESTROY){
 50             accMove = msg.acc;
 51             int desval = destroyUser(accMove);
 52             if(desval == -1){
 53                 printf("没有此ID\n");
 54                 msg.mtype = M_FAILED;
 55             }
 56             else if(desval == 0){
 57                 printf("销户失败!\n");
 58                 msg.mtype = M_FAILED;
 59             }
 60             else{
 61                 printf("销户成功!\n");
 62                 msg.mtype = M_SUCCESS;
 63             }
 64             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
 65         }
 66         else if(msg.mtype == M_SAVE){
 67             accMove = msg.acc;
 68             int saval = saveMoney(accMove,&accResult);
 69             if(saval == -1){
 70                 printf("没有此ID\n");
 71                 msg.mtype = M_FAILED;
 72             }
 73             else if(saval == 0){
 74                 printf("存钱失败!\n");
 75                 msg.mtype = M_FAILED;
 76             }
 77             else{
 78                 printf("存钱成功!\n");
 79                 msg.mtype = M_SUCCESS;
 80             }
 81             msg.acc = accResult;
 82             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
 83         }
 84         else if(msg.mtype == M_TAKE){
 85             accMove = msg.acc;
 86             int saval = getMoney(accMove,&accResult);
 87             if(saval == -1){
 88                 printf("没有此ID\n");
 89                 msg.mtype = M_FAILED;
 90             }
 91             else if(saval == 2){
 92                 printf("余额不足\n");
 93                 msg.mtype = M_FAILED;
 94             }
 95             else if(saval == 0){
 96                 printf("取钱失败!\n");
 97                 msg.mtype = M_FAILED;
 98             }
 99             else{
100                 printf("取钱成功!\n");
101                 msg.mtype = M_SUCCESS;
102             }
103             msg.acc = accResult;
104             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
105             
106         }
107         else if(msg.mtype == M_QUERY){
108             accMove = msg.acc;
109             int saval = checkMoney(accMove,&accResult);
110             if(saval == -1){
111                 printf("没有此ID\n");
112                 msg.mtype = M_FAILED;
113             }
114             else if(saval == 0){
115                 printf("查询失败!\n");
116                 msg.mtype = M_FAILED;
117             }
118             else{
119                 printf("查询成功!\n");
120                 msg.mtype = M_SUCCESS;
121             }
122             msg.acc = accResult;
123             if(msgsnd(msgid2,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
124 
125         }
126         else if(msg.mtype == M_TRANSF){
127             struct Account accto;
128             accMove = msg.acc;
129             if(msgrcv(msgid1,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);
130             accto = msg.acc;
131             int tra = moveMoney(accMove,accto,&accResult);
132             if(tra == -1){
133                 printf("没有此ID\n");
134                 msg.mtype = M_FAILED;
135             }
136             else if(tra == 0){
137                 printf("转账失败\n");
138                 msg.mtype = M_FAILED;
139             }
140             else if(tra == 2){
141                 printf("余额不足\n");
142                 msg.mtype = M_FAILED;
143             }
144             else{
145                 printf("转账成功\n");
146                 msg.mtype = M_SUCCESS;
147             }
148             msg.acc = accResult;
149             if(msgsnd(msgid2,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);
150             
151         }
152     }
153     return 0;
154 }
View Code

client.c:

  1 /* 客户端*/
  2 #include <stdio.h>
  3 #include "bank.h"
  4 #include <sys/types.h>
  5 #include <sys/ipc.h>
  6 #include <sys/msg.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 
 10 static int msgid1;//定义两个接受消息队列的id的变量
 11 static int msgid2;
 12 //获取消息队列函数,
 13 void getID(){
 14     msgid1 = msgget(key1,0);
 15     if(msgid1 == -1){
 16         perror("获取消息队列1失败");
 17         exit(-1);
 18     }
 19     msgid2 = msgget(key2,0);
 20     if(msgid2 == -1){
 21         perror("获取消息队列2失败");
 22         exit(-1);
 23     }
 24 }
 25 //开户函数
 26 void createUser(){
 27     struct Account acc;
 28     printf("请输入用户名:\n");
 29     scanf("%s",acc.name);
 30     printf("请输入密码:\n");
 31     scanf("%s",acc.password);
 32     printf("请输入金额:\n");
 33     scanf("%d",&acc.balance);
 34     struct Msg msg = {M_OPEN,acc};
 35     //获取消息队列
 36     getID();
 37     //将消息发送到消息队列1中
 38     msgsnd(msgid1,&msg,sizeof(msg.acc),0);
 39     //接受消息队列2中的消息
 40     msgrcv(msgid2,&msg,sizeof(msg.acc),0,0);
 41     if(msg.mtype == M_SUCCESS){
 42         printf("开户成功!\n");
 43         printf("您的ID为:%d\n",msg.acc.id);
 44     }
 45     else{
 46         printf("开户失败!\n");
 47     }
 48 }
 49 //销户
 50 void destroyUser(){
 51     struct Account acc;
 52     printf("请输入需要销户的ID:");
 53     scanf("%d",&acc.id);
 54     getchar();
 55     struct Msg msg;
 56     msg.mtype = M_DESTROY;
 57     msg.acc = acc;
 58     //获取消息ID
 59     getID();
 60     //将消息发送到消息队列1中
 61     if(msgsnd(msgid1,&msg,sizeof(msg.acc),0) == -1) perror("msgsnd"),exit(-1);
 62     //接收服务端消息
 63     if(msgrcv(msgid2,&msg,sizeof(msg.acc),0,0) == -1) perror("msgrcv"),exit(-1);
 64     if(msg.mtype == M_SUCCESS)
 65         printf("销户成功\n");
 66     else
 67         printf("销户失败\n");
 68 }
 69 //存钱
 70 void saveMoney(){
 71     struct Account acc;
 72     printf("请输入您的ID:");
 73     scanf("%d",&acc.id);
 74     getchar();
 75     printf("请输入您需要存的钱数:");
 76     scanf("%lf",&acc.balance);
 77     getchar();
 78 
 79     getID();
 80     struct Msg msg = {M_SAVE,acc};
 81     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
 82     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
 83     if(msg.mtype == M_SUCCESS){
 84         printf("存钱成功\n");
 85         printf("您的余额为:%lf\n",msg.acc.balance);
 86     }
 87     else
 88         printf("存钱失败!\n");
 89 }
 90 //取钱
 91 void getMoney(){
 92     struct Account acc;
 93     printf("请输入您的ID:");
 94     scanf("%d",&acc.id);
 95     getchar();
 96     printf("请输入您想取的金额:");
 97     scanf("%lf",&acc.balance);
 98     
 99     getID();
100     struct Msg msg = {M_TAKE,acc};
101 
102     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
103     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
104     if(msg.mtype == M_SUCCESS){
105         printf("取钱成功\n");
106         printf("您的余额为:%lf\n",msg.acc.balance);
107     }
108     else
109         printf("取钱失败!\n");
110 
111 }
112 //查询
113 void checkMoney(){
114     struct Account acc;
115     printf("请输入您的ID:");
116     scanf("%d",&acc.id);
117     getchar();
118     
119     struct Msg msg = {M_QUERY,acc};
120 
121     getID();
122     if(msgsnd(msgid1,&msg,sizeof(acc),0) == -1) perror("msgsnd"),exit(-1);
123     if(msgrcv(msgid2,&msg,sizeof(acc),0,0) == -1) perror("msgrcv"),exit(-1);
124     if(msg.mtype == M_SUCCESS){
125         printf("查询成功\n");
126         printf("您的余额为:%lf\n",msg.acc.balance);
127     }
128     else
129         printf("查询失败!\n");
130 }
131 //转账
132 void moveMoney(){
133     struct Account acc;
134     printf("请输入你的ID:%d:");
135     scanf("%d",&acc.id);
136     getchar();
137     printf("请输入你需要转账的金额:");
138     scanf("%lf",&acc.balance);
139     getchar();
140     
141     getID();
142 
143     struct Msg msg;
144     msg.mtype = M_TRANSF;
145     msg.acc = acc;
146 
147     if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);    
148     
149     printf("请输入需要转入的ID:");
150     scanf("%d",&acc.id);
151     msg.mtype = M_TRANSF;
152     msg.acc = acc;
153     if(msgsnd(msgid1,&msg,sizeof(struct Account),0) == -1) perror("msgsnd"),exit(-1);
154 
155     if(msgrcv(msgid2,&msg,sizeof(struct Account),0,0) == -1) perror("msgrcv"),exit(-1);
156 
157     if(msg.mtype == M_SUCCESS){
158         printf("转账成功!您的余额为:%lf",msg.acc.balance);
159     }
160     else
161         printf("转账失败!\n");
162 }
163 
164 //客户端界面
165 void mainPage(){
166     while(1){
167         printf("  欢迎使用迷你ATM机\n");
168         printf("---------------------\n");
169         printf("[1] 开户");
170         printf("      [2] 销户\n");
171         printf("[3] 存钱");
172         printf("      [4] 取钱\n");
173         printf("[5] 查询");
174         printf("      [6] 转账\n");
175         printf("[0] 退出\n");
176         printf("---------------------\n");
177         printf("请选择:\n");
178         int num = 0;
179         scanf("%d",&num);
180         switch(num){
181             case 1:createUser();break;
182             case 2:destroyUser();break;
183             case 3:saveMoney();break;
184             case 4:getMoney();break;
185             case 5:checkMoney();break;
186             case 6:moveMoney();break;
187             case 0:printf("谢谢使用,再见!\n");return ;
188             default:printf("输入错误\n");
189         }
190     }
191 }
192 int main(){
193     mainPage();
194     return 0;
195 }
View Code

dao.c:

  1 #include "dao.h"
  2 #include <unistd.h>
  3 #include <stdio.h>
  4 #include <sys/types.h>
  5 #include <fcntl.h>
  6 #include <stdlib.h>
  7 //定义一个文件来存储帐号
  8 const char* ID_FILE = "id.dat"; 
  9 //生成不重复的帐号
 10 int generator_id(){
 11     static int x = 100000;
 12     if(access(ID_FILE,F_OK)==-1){//判断文件是否存在,不存在返回-1
 13         //不存在就创建
 14         int fd = open(ID_FILE,O_WRONLY|O_CREAT|O_EXCL,0600);
 15         if(fd == -1){
 16             perror("文件打开失败");
 17             return -1;
 18         }
 19         write(fd,&x,sizeof(x));//写入文件
 20         close(fd);
 21         return x;
 22     }
 23     //如果文件存
 24     int fd = open(ID_FILE,O_RDWR);
 25     if(fd == -1){
 26         perror("文件打开失败");
 27         return -1;
 28     }
 29     //将文件中的数值读到x中
 30     read(fd,&x,sizeof(x));
 31     x++;//保证帐号唯一
 32     //将读写位置置到文件开始头
 33     lseek(fd,0,SEEK_SET);
 34     //再将x的值写到文件中,覆盖原来的x
 35     write(fd,&x,sizeof(x));
 36     close(fd);
 37     return x;
 38 }
 39 
 40 //将一个新帐号 存到文件中
 41 int createUser(struct Account acc){
 42     char filename[20]={};
 43     sprintf(filename,"%d.dat",acc.id);//为每个帐号建立一个文件
 44     int fd = open(filename,O_WRONLY|O_CREAT|O_EXCL,0600);
 45     if(fd == -1){
 46         perror("创建帐户文件失败");
 47         return -1;
 48     }
 49     if(write(fd,&acc,sizeof(acc)) < 0){
 50         return -1;
 51     }
 52     close(fd);
 53     printf("创建用户成功\n");
 54     return 0;
 55 }
 56 
 57 //销户功能
 58 int destroyUser(struct Account acc){
 59     char filename[20];
 60     sprintf(filename,"%d.dat",acc.id);
 61     if(access(filename,F_OK) == -1)
 62         return -1;//返回 -1 表示没有这个ID
 63     if(remove(filename) == -1)
 64         return 0;//返回 0 表示 销户失败
 65     else 
 66         return 1;//返回 1 表示 销户成功
 67     
 68 }
 69 
 70 //存钱功能
 71 int saveMoney(struct Account acc, struct Account *p){
 72     char filename[20];
 73     sprintf(filename,"%d.dat",acc.id);
 74     if(access(filename,F_OK) == -1)
 75         return -1;
 76     int fd;
 77     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
 78 
 79     if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1);
 80 
 81     p->balance += acc.balance;
 82 
 83     //printf("存过钱:%lf",p->balance);
 84     lseek(fd,0,SEEK_SET);
 85     if(write(fd,p,sizeof(struct Account)) < 0)
 86         return 0;
 87     else
 88         return 1;
 89     close(fd);
 90 }
 91 
 92 //取钱
 93 int getMoney(struct Account acc, struct Account *p){
 94     char filename[20];
 95     sprintf(filename,"%d.dat",acc.id);
 96     if(access(filename,F_OK) == -1)
 97         return -1;
 98     int fd;
 99     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
100 
101     if(read(fd,p,sizeof(struct Account)) < 0) perror("read"),exit(-1);
102 
103     if(p->balance < acc.balance){
104         return 2;    //余额不足
105     }
106 
107     p->balance -= acc.balance;
108     //printf("存过钱:%lf",p->balance);
109     lseek(fd,0,SEEK_SET);
110     if(write(fd,p,sizeof(struct Account)) < 0)
111         return 0;
112     else
113         return 1;
114     close(fd);
115 }
116 
117 
118 //查询余额功能
119 int checkMoney(struct Account acc, struct Account *p){
120     char filename[20];
121     sprintf(filename,"%d.dat",acc.id);
122     if(access(filename,F_OK) == -1)
123         return -1;
124     int fd;
125     if((fd = open(filename,O_RDWR)) == -1) perror("open"),exit(-1);
126 
127     if(read(fd,p,sizeof(struct Account)) < 0)
128         return 0;
129     else
130         return 1;
131     close(fd);
132 }
133 
134 //转账功能 acc1 --> from  acc2 --> to
135 int moveMoney(struct Account acc1, struct Account acc2, struct Account *p){
136     char filename[20];
137     sprintf(filename,"%d.dat",acc1.id);
138     if(access(filename,F_OK) == -1)
139         return -1;
140     int fdfrom,fdto;
141     if((fdfrom = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);
142     if(read(fdfrom,p,sizeof(struct Account)) < 0)    return 0;
143     //判断金额是否足够
144     if(p->balance < acc1.balance) return 2;
145     //判断转入的用户是否存在
146     sprintf(filename,"%d.dat",acc2.id);
147     if(access(filename,F_OK) == -1)
148         return -1;
149 
150     p->balance -= acc1.balance;
151     lseek(fdfrom,0,SEEK_SET);
152     if(write(fdfrom,p,sizeof(struct Account)) < 0) perror("write"),exit(-1);
153     close(fdfrom);
154 
155     if((fdto = open(filename,O_RDWR)) < 0) perror("open"),exit(-1);
156     if(read(fdto,&acc2,sizeof(struct Account)) < 0) perror("open"),exit(-1);
157     acc2.balance += acc1.balance;
158     lseek(fdto,0,SEEK_SET);    //需要把文件指针移动到文件开头
159     if(write(fdto,&acc2,sizeof(struct Account)) < 0){
160         return 0;
161         close(fdto);
162     }
163     else{
164         close(fdto);
165         return 1;
166     }
167     
168 }
View Code

 

link:  

  server:

    gcc server.c bank.c -o server

  client:  

    gcc client.c bank.c -o client

  open:

    gcc open.c bank.c dao.c -o open

推荐阅读