功能描述: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 }
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 }
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 }
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