⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 本实验模拟ATM取款功能。本程序比较简单
💻 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 + -