📄 server.c
字号:
//server
/****************************************************
* 《ATM 服务模型服务端代码》 *
* 2003级计算机4班 030300639 许贻福 *
* 2005.12.28 *
****************************************************/#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<sys/shm.h>#define MSGKEYS 1 //the server's key#define MSGKEYR 2 //the client's key#define SHMKEY 3#define MAXNUM 6 #define PSWSIZE 6struct msgform{ long mtype; unsigned int mtext[256];}msnd,mrcv;typedef struct{ unsigned int no; char name[20]; char password[PSWSIZE]; unsigned int money;}people;people* addr;FILE* fp;int i,shmid,sndid,rcvid,cpid;
void LoadData();//load the account's data from the file "data.txt"void SaveData();//save the changed information in the file "data.txt"void Deal_ModifyPassWord();void Deal_DrawMoney();void Deal_Transfer();
bool Search_no();
bool Print(int i);
main(){ LoadData();//load the data from the file to the memory rcvid=msgget(MSGKEYR,IPC_CREAT|0600);//建立与客户端进程相同的消息队列,对应KEY=2 sndid=msgget(MSGKEYS,IPC_CREAT|0666);//建立服务端的消息队列,对应KEY=1 int p1,p2,p3; while((p1=fork())==-1); if(p1==0) {//the child process deal the modify password request while(1) Deal_ModifyPassWord(); } else { while((p2=fork())==-1); if(p2==0) {//the child process deal the draw money request while(1) Deal_DrawMoney(); } else { while((p3=fork())==-1); if(p3==0) {//the child process deal the transfer money request while(1) Deal_Transfer(); } else {//父进程善后 signal(SIGINT,SIG_IGN); wait(0); wait(0); wait(0); SaveData();//save the changed data to the file } } }}
bool Print(int i)
{
if(fwrite(&P[i].no,sizeof(people.no),1,fp)!=1||
fwrite(&P[i].name,sizeof(people.name),1,fp)!=1||
fwrite(&P[i].password,sizeof(people.password),1,fp)!=1||
fwrite(&P[i].money,sizeof(people.money),1,fp)!=1
)
return -1;
else return 0;
}
int Choice()
{
char c;
printf("请输入 'Y/N':");
while(c=getchar())
switch(c)
{
case 'y':
case 'Y':return 1;
case 'n':
case 'N':return 0;
default:;
}
}
void InitializeData()
{
people P[MAXNUM];
fp=fopen("data.txt","w");//open the file
printf("正在初试化...\n");
printf("你必须初始化 %d 个帐户的信息\n",MAXNUM);
printf("帐号\t姓名\t密码\t金额\n");
for(i=0;i<MAXNUM;i++)
{
scanf("%u%s%s%u",&P[i].no,&P[i].name,&P[i].password,&P[i].money);
if(Print(i)==-1)//writing...
printf("文件写入出错!\n");
}
fclose(fp);//close the file
}
void LoadData()
{//load the data.txt's content to the memery
if((fp=fopen("data.txt","r"))!=NULL)//open the file
{
printf("帐户数据已存在,您要初始化帐户数据吗?\n");
if(Choice()==1)
{
printf("您确认要初始化帐户数据吗,这样将清除原有数据?\n"
if(Choice()==1)
InitializeData();
}
}
else
{
printf("文件 data.txt 不存在!\n");
printf("请先初始化帐户数据!\n");
InitializeData();
}
shmid=shmget(SHMKEY,sizeof(people)*MAXNUM,IPC_CREAT);
addr=(people*)shmat(shmid,0,0);
people P[MAXNUM];
for(i=0;i<MAXNUM;i++)
{
if((fread(&P[i],sizeof(people),1,fp))!=1)//reading...
printf("文件读出失败!\n");
addr[i].no=P[i].no;
strcpy(addr[i].name,P[i].name);
strcpy(addr[i].password,P[i].password);
addr[i].money=P[i].money;
}
fclose(fp);//close the file
}
void SaveData()
{
fp=fopen("data.txt","w");//open the file
for(i=0;i<MAXNUM;i++)
if((fwrite(&addr[i],sizeof(people),1,fp))!=1)//writing...
printf("File write error!\n");
fclose(fp);//close the file
shmctl(shmid,IPC_RMID,0);
msgctl(sndid,IPC_RMID,0);
msgctl(rcvid,IPC_RMID,0);
}void Deal_ModifyPassWord(){//mtype=1,mtext[0]为客户端进程id,mtext[1]为帐号no,(mtext[2]~mtext[1+PSWSIZE])指向要修改的密码 char psw[PSWSIZE]; int n1,i; msgrcv(rcvid,&mrcv,256,1,0);//接收消息 cpid=mrcv.mtext[0]; n1=mrcv.mtext[1]-1; for(i=0;i<PSWSIZE;i++) psw[i]=(char)mrcv.mtext[2+i]; //dealing... strcpy(addr[n1].password,psw); // printf("操作后,帐号%u\t%s\t的新密码为%s\n",n1+1,addr[n1].name,psw); msnd.mtype=cpid; strcpy((char*)msnd.mtext,"修改密码成功!"); while(msgsnd(sndid,&msnd,256,0)==-1);//发送消息 }void Deal_DrawMoney(){//mtype=2,mtext[0]为客户端进程id,mtext[1]为帐号no,mtext[2]要取的钱 unsigned int m; int n1; msgrcv(rcvid,&mrcv,256,2,0);//接收客户的取款的修改请求,消息类型为2 cpid=mrcv.mtext[0]; n1=mrcv.mtext[1]-1; m=mrcv.mtext[2]; //dealing... addr[n1].money-=m; // printf("操作后,帐号%u\t%s\t剩下:%u元\n",n1+1,addr[n1].name,addr[n1].money); msnd.mtype=cpid; strcpy((char*)msnd.mtext,"取钱成功!"); while(msgsnd(sndid,&msnd,256,0)==-1);//发送应答消息 }void Deal_Transfer(){//mtype=3,mtext[0]为客户端进程id,mtext[1]为转帐人帐号no,mtext[2]为要转的钱,mtext[3]为要转向的帐号no unsigned int m; int n1,n2; msgrcv(rcvid,&mrcv,256,3,0);//接受消息 cpid=mrcv.mtext[0]; n1=mrcv.mtext[1]-1; m=mrcv.mtext[2]; n2=mrcv.mtext[3]-1; //dealing... addr[n1].money-=m; addr[n2].money+=m; // printf("操作后,帐号%u\t%s\t剩下%u元\n",n1+1,addr[n1].name,addr[n1].money); printf("操作后,帐号%u\t%s\t剩下%u元\n",n2+1,addr[n2].name,addr[n2].money); msnd.mtype=cpid; strcpy((char*)msnd.mtext,"转帐成功!"); while(msgsnd(sndid,&msnd,256,0)==-1);//发送应答消息}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -