[Linux operating system] Detailed analysis of bank management system <client> code based on message queue

This is a detailed explanation of the project code of a bank management system client based on information queues. It mainly introduces the operation of account opening, deposits, withdrawals and other tasks on the client. The code is relatively simple, but each piece of code is explained in detail. The source code Mainly from:
Linux system programming stage project: Bank management system based on message queue.
This article is a detailed explanation based on its code. It is also a record of my detailed research after reading his blog.
Insert image description here



Header files and structures

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int g_reqid; //作为请求的消息队列的返回id
int g_resid;  //作为应答消息队列的返回id
typedef struct msgbuf{
    
    
    long mtype;         //消息类型
    char id[100];       //账户
    char name[256];     //用户名
    char pw[9];        //密码
    float money;       //银行卡余额
}userm;
typedef struct tag_OpenRespond{
    
    
  long   type;
  char   id[100];      //账户
  char   msg[256];
  float  money;       //银行卡余额
}RES;                 //让客户端从应答消息队列读到的反馈存到这里

main function

int main()
{
    
    
    while(1)
    {
    
    
        menu();
        int a;
        printf("请输入要执行的操作!\n");
        scanf("%d",&a);
        switch(a)
        {
    
    
            case 1:Account();break;//开户
            case 2:Deposit();break;//存款
            case 3:withdrawal();break;//取款
            case 4:Inquire();break;//查询
            case 5:Transfer();break;//转账
            case 6:Logout();break;//注销
            case 7:
                return 0;

        }
    }
}

The main function is very simple:

  • Mainly it is a loop body while(1);
  • Then output a directory menu();
  • The user inputs a numerical value to select the function to be operated; the corresponding is the following switchselection statement;
  • If the user inputs 1, it means opening an account, and the corresponding function is Account();
  • If the user inputs 2, it is a deposit, and the corresponding function is Deposit();
  • If the user inputs 3, it means withdrawal, and the corresponding function is Withdrawal();
  • If the user inputs 4, it is a query, and the corresponding function is Inquire();
  • If the user enters 5, it is a transfer, and the corresponding function is Transfer();
  • If the user enters 6, it means logging out, and the corresponding function is Logout();
  • If the user enters 7, it will exit.

The next step is to solve the problems of these functions step by step:


menu

void menu()
{
    
    
    printf("*********欢迎来到小黑银行!************\n");
    printf("**************1.开户******************\n");
    printf("**************2.存款******************\n");
    printf("**************3.取款******************\n");
    printf("**************4.查询******************\n");
    printf("**************5.转账******************\n");
    printf("**************6.销户******************\n");
    printf("**************7.退出******************\n");
}

It is very simple to implement the menu function. It only requires standard output. There is no need to consider the port issue. The port is implemented by the following function.


1. Open an account

void Account()
{
    
    
    key_t kid1,kid2;

    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;//错误提示
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1) 
    {
    
       
        perror("msgget");
        return;
    }   
    
    userm a;
    printf("请输入要注册的身份号!\n");
    scanf("%s",a.id);

    printf("请输入要注册的用户名!\n");
    scanf("%s",a.name);

    printf("请输入要注册的密码!\n");
    scanf("%s",a.pw);

    printf("请输入要注册的余额!\n");
    scanf("%f",&a.money);
    //往请求消息队列写
    a.mtype = 1;   //消息类型为1,开户用
    msgsnd(g_reqid,&a,sizeof(userm)-sizeof(long),0);

    //读应答消息队列
    RES buf;
    msgrcv(g_resid,&buf,sizeof(buf),1,0);  //1类消息,开户用
    printf("%s\n",buf.msg);

    return;

}

Code explanation

This code is a C language function that opens two message queues and writes and reads messages from them.

First, use ftoka function to generate two key values ​​that uniquely identify the message queue. ftokThe function requires a file path and an integer value, and it generates a unique key value based on these parameters.

Then, use msggetfunctions to open the request message queue and the response message queue. msggetThe function accepts two parameters, one is the key value and the other is the flag. IPC_CREATIndicates that if the message queue does not exist, create a new one, 0644indicating that the permission is set to read and write.

usermNext, a structure variable named is defined ato store the user's registration information. Then the user is prompted to enter the identity number, user name, password and balance through printfthe and scanffunctions respectively, and the values ​​entered by the user are stored in the corresponding fields of the structure variables a.

aAfter that, the field is set mtypeto 1, indicating that this message is for account opening. Then use msgsndthe function to write the structure variable ato the request message queue. msgsndThe function accepts five parameters, which are the ID of the message queue, the pointer to the message, the size of the message, the type of the message and the flag bit. The message type here is 1, which means it is used to open an account.

Finally, use msgrcvthe function to read messages from the reply message queue. msgrcvThe function accepts five parameters, which are the ID of the message queue, the pointer to the message, the size of the message, the type of the message and the flag bit. The message type here is 1, which means it is used to open an account. The read message is stored in bufa structure variable named. Then use printfthe function to print out the contents of the message.

The purpose of the entire function is to write the user's registration information to the request message queue, and read the account opening results from the response message queue and print them out.


2. Deposit

void Deposit()//存款业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm c;
    printf("请输入要存款用户的身份号!\n");
    scanf("%s",c.id);
   
    printf("请输入要存款用户的用户名!\n");
    scanf("%s",c.name);
    
    printf("请输入要存款用户的密码!\n");
    scanf("%s",c.pw);
   
    printf("请输入要存款的金额!\n");
    scanf("%f",&c.money);
    //往请求消息队列写
    c.mtype = 2;   //消息类型为2,存款用
    msgsnd(g_reqid,&c,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf2;
    msgrcv(g_resid,&buf2,sizeof(buf2),2,0);  //2类消息,存款用
    printf("%s\n",buf2.msg);
    
    return;
}

1. Create the key value of the message queue

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • ftokThe function is used to generate a unique key value as an identifier for creating a message queue.
  • The first parameter is a pathname used to generate the key value.
  • The second parameter is an integer used to generate the key value.
  • Here, two different paths and integers are used as parameters to generate two different key values.

2. Open the request message queue

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • msggetFunction is used to open or create a message queue.
  • The first parameter is the key value of the message queue.
  • The second parameter is a flag, IPC_CREATwhich means to create the message queue if it does not exist, 0644which means to set permissions.
  • The function returns the identifier of the message queue. If the return value is -1, it means that the opening or creation failed.

3. Open the reply message queue

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Also use msggetthe function to open or create a message queue, this time using the second key value.
  • If opening or creation fails, an error message will be printed and returned.

4. Enter deposit information

userm c;
printf("请输入要存款用户的身份号!\n");
scanf("%s",c.id);

printf("请输入要存款用户的用户名!\n");
scanf("%s",c.name);

printf("请输入要存款用户的密码!\n");
scanf("%s",c.pw);

printf("请输入要存款的金额!\n");
scanf("%f",&c.money);
  • Create a structure named to store user-related information c.userm
  • Enter the user's identity number, username, password and deposit amount in sequence.

5. Write the request to the message queue

c.mtype = 2;   //消息类型为2,存款用
msgsnd(g_reqid,&c,sizeof(userm)-sizeof(long),0);
  • Set the message type to 2, indicating that this is a deposit request.
  • Use msgsndthe function to cwrite the structure to the request message queue.
  • sizeof(userm)-sizeof(long)Represents the size of the message to be sent, minus longthe size of the message type field of type.

6. Read the response message queue

RES buf2;
msgrcv(g_resid,&buf2,sizeof(buf2),2,0);  //2类消息,存款用
printf("%s\n",buf2.msg);
  • Create a structure named to receive the response message buf2.RES
  • Use msgrcvthe function to read messages from the reply message queue.
  • The first parameter is the identifier of the message queue.
  • The second parameter is the buffer to receive the message.
  • The third parameter is the size of the received message.
  • The fourth parameter is the message type, here it is 2, indicating the response message for receiving the deposit.
  • The last parameter is a flag, 0 indicates the default behavior.
  • Print the received reply message.

7. Return

return;
  • End the execution of the deposit business function and return to the place where it was called.

3. Withdrawal

void withdrawal()//取款业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm d;
    printf("请输入要取款用户的身份号!\n");
    scanf("%s",d.id);
   
    printf("请输入要取款用户的用户名!\n");
    scanf("%s",d.name);
    
    printf("请输入要取款用户的密码!\n");
    scanf("%s",d.pw);
   
    printf("请输入要取款的金额!\n");
    scanf("%f",&d.money);
    //往请求消息队列写
    d.mtype = 3;   //消息类型为3,取款用
    msgsnd(g_reqid,&d,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf3;
    msgrcv(g_resid,&buf3,sizeof(buf3),3,0);  //3类消息,取款用
    printf("%s\n",buf3.msg);
    
    return;
}

1. Create the key value of the message queue

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • ftokThe function is used to generate a unique key value as an identifier for creating a message queue.
  • The first parameter is a pathname used to generate the key value.
  • The second parameter is an integer used to generate the key value.
  • Here, two different paths and integers are used as parameters to generate two different key values.

2. Open the request message queue

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • msggetFunction is used to open or create a message queue.
  • The first parameter is the key value of the message queue.
  • The second parameter is a flag, IPC_CREATwhich means to create the message queue if it does not exist, 0644which means to set permissions.
  • The function returns the identifier of the message queue. If the return value is -1, it means that the opening or creation failed.

3. Open the reply message queue

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Also use msggetthe function to open or create a message queue, this time using the second key value.
  • If opening or creation fails, an error message will be printed and returned.

4. Enter withdrawal information

userm d;
printf("请输入要取款用户的身份号!\n");
scanf("%s",d.id);

printf("请输入要取款用户的用户名!\n");
scanf("%s",d.name);

printf("请输入要取款用户的密码!\n");
scanf("%s",d.pw);

printf("请输入要取款的金额!\n");
scanf("%f",&d.money);
  • Create a structure named to store user-related information d.userm
  • Enter the user's identity number, username, password and withdrawal amount in sequence.

5. Write the request to the message queue

d.mtype = 3;   //消息类型为3,取款用
msgsnd(g_reqid,&d,sizeof(userm)-sizeof(long),0);
  • Set the message type to 3, indicating that this is a withdrawal request.
  • Use msgsndthe function to dwrite the structure to the request message queue.
  • sizeof(userm)-sizeof(long)Represents the size of the message to be sent, minus longthe size of the message type field of type.

6. Read the response message queue

RES buf3;
msgrcv(g_resid,&buf3,sizeof(buf3),3,0);  //3类消息,取款用
printf("%s\n",buf3.msg);
  • Create a structure named to receive the response message buf3.RES
  • Use msgrcvthe function to read messages from the reply message queue.
  • The first parameter is the identifier of the message queue.
  • The second parameter is the buffer to receive the message.
  • The third parameter is the size of the received message.
  • The fourth parameter is the message type, here it is 3, which means receiving the response message for withdrawal.
  • The last parameter is a flag, 0 indicates the default behavior.
  • Print the received reply message.

7. Return

return;
  • End the execution of the withdrawal business function and return to the place where it was called.

4. Inquiry

void Inquire()//查询业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm e;
    printf("请输入要查询用户的身份号!\n");
    scanf("%s",e.id);
   
    printf("请输入要查询用户的用户名!\n");
    scanf("%s",e.name);
    
    printf("请输入要查询用户的密码!\n");
    scanf("%s",e.pw);
   
    //printf("请输入要查询的金额!\n");
    //scanf("%f",&d.money);
    //往请求消息队列写
    e.mtype = 4;   //消息类型为4,查询用
    msgsnd(g_reqid,&e,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf4;
    msgrcv(g_resid,&buf4,sizeof(buf4),4,0);  //消息类型为4,查询用
    printf("%s\n",buf4.msg);
    
    return;
}

1. Create the key value of the message queue

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Also use ftokthe function to generate two different key values ​​for creating message queues.

2. Open the request message queue

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Use msggetthe function to open or create a request message queue.

3. Open the reply message queue

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Also use msggetthe function to open or create a reply message queue.

4. Enter query information

userm e;
printf("请输入要查询用户的身份号!\n");
scanf("%s",e.id);

printf("请输入要查询用户的用户名!\n");
scanf("%s",e.name);

printf("请输入要查询用户的密码!\n");
scanf("%s",e.pw);
  • Create a structure named to store relevant information of the query user e.userm
  • Enter the user's identity number, username and password in sequence.

5. Write the request to the message queue

e.mtype = 4;   //消息类型为4,查询用
msgsnd(g_reqid,&e,sizeof(userm)-sizeof(long),0);
  • Set the message type to 4, indicating that this is a query request.
  • Use msgsndthe function to ewrite the structure to the request message queue.
  • sizeof(userm)-sizeof(long)Represents the size of the message to be sent, minus longthe size of the message type field of type.

6. Read the response message queue

RES buf4;
msgrcv(g_resid,&buf4,sizeof(buf4),4,0);  //消息类型为4,查询用
printf("%s\n",buf4.msg);
  • Create a structure named to receive the response message buf4.RES
  • Use msgrcvthe function to read messages from the reply message queue.
  • The first parameter is the identifier of the message queue.
  • The second parameter is the buffer to receive the message.
  • The third parameter is the size of the received message.
  • The fourth parameter is the message type, here it is 4, which means receiving the query response message.
  • The last parameter is a flag, 0 indicates the default behavior.
  • Print the received reply message.

7. Return

return;
  • End the execution of the query business function and return to the place where it was called.

5. Transfer

void Transfer()//转账业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm f1,f2;
    printf("请输入转账用户的身份号!\n");
    scanf("%s",f1.id);
   
    printf("请输入转账用户的用户名!\n");
    scanf("%s",f1.name);
    
    printf("请输入转账用户的密码!\n");
    scanf("%s",f1.pw);
   
    printf("请输入要转账的金额!\n");
    scanf("%f",&f1.money);
    
    printf("请输入被转账用户的身份号!\n");
    scanf("%s",f2.id);
    //往请求消息队列写
    f1.mtype = 5;   //消息类型为5,转账用,第一条消息,转账用户用
    msgsnd(g_reqid,&f1,sizeof(userm)-sizeof(long),0);
    f2.mtype = 55;   //消息类型为55,转账用,第二条消息,被转账用户用
    msgsnd(g_reqid,&f2,sizeof(userm)-sizeof(long),0);
    //读应答消息队列
    RES buf3;
    msgrcv(g_resid,&buf3,sizeof(buf3),5,0);  //5类消息,转账用
    printf("%s\n",buf3.msg);
    
    
    RES buf4;
    msgrcv(g_resid,&buf4,sizeof(buf4),55,0);  //55类消息,转账用
    printf("%s\n",buf4.msg);
    return;
}

1. Create the key value of the message queue

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Also use ftokthe function to generate two different key values ​​for creating message queues.

2. Open the request message queue

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Use msggetthe function to open or create a request message queue.

3. Open the reply message queue

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Also use msggetthe function to open or create a reply message queue.

4. Enter the transfer user information

userm f1,f2;
printf("请输入转账用户的身份号!\n");
scanf("%s",f1.id);

printf("请输入转账用户的用户名!\n");
scanf("%s",f1.name);

printf("请输入转账用户的密码!\n");
scanf("%s",f1.pw);

printf("请输入要转账的金额!\n");
scanf("%f",&f1.money);
  • Create two structures named and to store information about the transferring user and the transferred user respectively f1.f2userm
  • Enter the transfer user's identity number, username, password and transfer amount in sequence.

5. Write the request to the message queue

f1.mtype = 5;   //消息类型为5,转账用,第一条消息,转账用户用
msgsnd(g_reqid,&f1,sizeof(userm)-sizeof(long),0);
f2.mtype = 55;   //消息类型为55,转账用,第二条消息,被转账用户用
msgsnd(g_reqid,&f2,sizeof(userm)-sizeof(long),0);
  • Set the message type to 5 and 55, indicating that these are two messages for the transfer request.
  • Use msgsndthe function to write the f1and f2structures into the request message queue respectively.
  • sizeof(userm)-sizeof(long)Represents the size of the message to be sent, minus longthe size of the message type field of type.

6. Read the response message queue

RES buf3;
msgrcv(g_resid,&buf3,sizeof(buf3),5,0);  //5类消息,转账用
printf("%s\n",buf3.msg);


RES buf4;
msgrcv(g_resid,&buf4,sizeof(buf4),55,0);  //55类消息,转账用
printf("%s\n",buf4.msg);
  • Create two structures named and for receiving response messages buf3.buf4RES
  • Use msgrcvthe function to read messages from the reply message queue.
  • The first parameter is the identifier of the message queue.
  • The second parameter is the buffer to receive the message.
  • The third parameter is the size of the received message.
  • The fourth parameter is the message type, here respectively 5 and 55, indicating the response message for receiving the transfer.
  • The last parameter is a flag, 0 indicates the default behavior.
  • Print the received reply message.

7. Return

return;
  • End the execution of the transfer business function and return to the place where it was called.

6. Cancellation

void Logout()
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm b;
    printf("请输入要注销用户的身份号!\n");
    scanf("%s",b.id);
   
    printf("请输入要注销用户的用户名!\n");
    scanf("%s",b.name);
    
    printf("请输入要注销用户的密码!\n");
    scanf("%s",b.pw);
   
    printf("请输入要注销用户的余额!\n");
    scanf("%f",&b.money);
    //往请求消息队列写
    b.mtype = 6;   //消息类型为6,注销用
    msgsnd(g_reqid,&b,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf1;
    msgrcv(g_resid,&buf1,sizeof(buf1),6,0);  //6类消息,注销用
    printf("%s\n",buf1.msg);
    
    return;
}

1. Create the key value of the message queue

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Also use ftokthe function to generate two different key values ​​for creating message queues.

2. Open the request message queue

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Use msggetthe function to open or create a request message queue.

3. Open the reply message queue

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Also use msggetthe function to open or create a reply message queue.

4. Enter the logout user information

userm b;
printf("请输入要注销用户的身份号!\n");
scanf("%s",b.id);

printf("请输入要注销用户的用户名!\n");
scanf("%s",b.name);

printf("请输入要注销用户的密码!\n");
scanf("%s",b.pw);

printf("请输入要注销用户的余额!\n");
scanf("%f",&b.money);
  • Create a structure named bto usermstore information about logged-out users.
  • Enter the identity number, username, password and balance of the user to be logged out in sequence.

5. Write the request to the message queue

b.mtype = 6;   //消息类型为6,注销用
msgsnd(g_reqid,&b,sizeof(userm)-sizeof(long),0);
  • Set the message type to 6, indicating that this is a logout request message.
  • Use msgsndthe function to bwrite the structure to the request message queue.
  • sizeof(userm)-sizeof(long)Represents the size of the message to be sent, minus longthe size of the message type field of type.

6. Read the response message queue

RES buf1;
msgrcv(g_resid,&buf1,sizeof(buf1),6,0);  //6类消息,注销用
printf("%s\n",buf1.msg);
  • Create a structure named buf1to RESreceive the response message.
  • Use msgrcvthe function to read messages from the reply message queue.
  • The first parameter is the identifier of the message queue.
  • The second parameter is the buffer to receive the message.
  • The third parameter is the size of the received message.
  • The fourth parameter is the message type, here it is 6, which means receiving the logout response message.
  • The last parameter is a flag, 0 indicates the default behavior.
  • Print the received reply message.

7. Return

return;
  • End the execution of the logout user business function and return to the place where it was called.

overall code

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int g_reqid; //作为请求的消息队列的返回id
int g_resid;  //作为应答消息队列的返回id
typedef struct msgbuf{
    
    
    long mtype;         //消息类型
    char id[100];       //账户
    char name[256];     //用户名
    char pw[9];        //密码
    float money;       //银行卡余额
}userm;
typedef struct tag_OpenRespond{
    
    
  long   type;
  char   id[100];      //账户
  char   msg[256];
  float  money;       //银行卡余额
}RES;                 //让客户端从应答消息队列读到的反馈存到这里
void menu();
void Account();//开户
void Deposit();//存款
void withdrawal();//取款
void Inquire();//查询
void Transfer();//转账
void Logout();//注销
int main()
{
    
    
    while(1)
    {
    
    
        menu();
        int a;
        printf("请输入要执行的操作!\n");
        scanf("%d",&a);
        switch(a)
          {
    
    
            case 1:Account();break;//开户
            case 2:Deposit();break;//存款
            case 3:withdrawal();break;//取款
            case 4:Inquire();break;//查询
            case 5:Transfer();break;//转账
            case 6:Logout();break;//注销
            case 7:
                return 0;
            
        }
    }
}
void Account()
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    
    userm a;
    printf("请输入要注册的身份号!\n");
    scanf("%s",a.id);
   
    printf("请输入要注册的用户名!\n");
    scanf("%s",a.name);
    
    printf("请输入要注册的密码!\n");
    scanf("%s",a.pw);
   
    printf("请输入要注册的余额!\n");
    scanf("%f",&a.money);
    //往请求消息队列写
    a.mtype = 1;   //消息类型为1,开户用
    msgsnd(g_reqid,&a,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf;
    msgrcv(g_resid,&buf,sizeof(buf),1,0);  //1类消息,开户用
    printf("%s\n",buf.msg);
    
    return;
    
}
void Logout()
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm b;
    printf("请输入要注销用户的身份号!\n");
    scanf("%s",b.id);
   
    printf("请输入要注销用户的用户名!\n");
    scanf("%s",b.name);
    
    printf("请输入要注销用户的密码!\n");
    scanf("%s",b.pw);
   
    printf("请输入要注销用户的余额!\n");
    scanf("%f",&b.money);
    //往请求消息队列写
    b.mtype = 6;   //消息类型为6,注销用
    msgsnd(g_reqid,&b,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf1;
    msgrcv(g_resid,&buf1,sizeof(buf1),6,0);  //6类消息,注销用
    printf("%s\n",buf1.msg);
    
    return;
}
void Deposit()//存款业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm c;
    printf("请输入要存款用户的身份号!\n");
    scanf("%s",c.id);
   
    printf("请输入要存款用户的用户名!\n");
    scanf("%s",c.name);
    
    printf("请输入要存款用户的密码!\n");
    scanf("%s",c.pw);
   
    printf("请输入要存款的金额!\n");
    scanf("%f",&c.money);
    //往请求消息队列写
    c.mtype = 2;   //消息类型为2,存款用
    msgsnd(g_reqid,&c,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf2;
    msgrcv(g_resid,&buf2,sizeof(buf2),2,0);  //2类消息,存款用
    printf("%s\n",buf2.msg);
    
    return;
}
void withdrawal()//取款业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm d;
    printf("请输入要取款用户的身份号!\n");
    scanf("%s",d.id);
   
    printf("请输入要取款用户的用户名!\n");
    scanf("%s",d.name);
    
    printf("请输入要取款用户的密码!\n");
    scanf("%s",d.pw);
   
    printf("请输入要取款的金额!\n");
    scanf("%f",&d.money);
    //往请求消息队列写
    d.mtype = 3;   //消息类型为3,取款用
    msgsnd(g_reqid,&d,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf3;
    msgrcv(g_resid,&buf3,sizeof(buf3),3,0);  //3类消息,取款用
    printf("%s\n",buf3.msg);
    
    return;
}
void Inquire()
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm e;
    printf("请输入要查询用户的身份号!\n");
    scanf("%s",e.id);
   
    printf("请输入要查询用户的用户名!\n");
    scanf("%s",e.name);
    
    printf("请输入要查询用户的密码!\n");
    scanf("%s",e.pw);
   
    //printf("请输入要查询的金额!\n");
    //scanf("%f",&d.money);
    //往请求消息队列写
    e.mtype = 4;   //消息类型为4,查询用
    msgsnd(g_reqid,&e,sizeof(userm)-sizeof(long),0);
    
    //读应答消息队列
    RES buf4;
    msgrcv(g_resid,&buf4,sizeof(buf4),4,0);  //消息类型为4,查询用
    printf("%s\n",buf4.msg);
    
    return;
}
void Transfer()//转账业务
{
    
    
    key_t kid1,kid2;
   
    kid1 = ftok("/home/whs/002/0706",1); //键值
    kid2 = ftok("/home/whs/002/0706",2);
    g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
    if(g_reqid== -1)
    {
    
    
        perror("msgget");
        return;
    }
 
    g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
    if(g_resid == -1)
    {
    
    
        perror("msgget");
        return;
    }
    userm f1,f2;
    printf("请输入转账用户的身份号!\n");
    scanf("%s",f1.id);
   
    printf("请输入转账用户的用户名!\n");
    scanf("%s",f1.name);
    
    printf("请输入转账用户的密码!\n");
    scanf("%s",f1.pw);
   
    printf("请输入要转账的金额!\n");
    scanf("%f",&f1.money);
    
    printf("请输入被转账用户的身份号!\n");
    scanf("%s",f2.id);
    //往请求消息队列写
    f1.mtype = 5;   //消息类型为5,转账用,第一条消息,转账用户用
    msgsnd(g_reqid,&f1,sizeof(userm)-sizeof(long),0);
    f2.mtype = 55;   //消息类型为55,转账用,第二条消息,被转账用户用
    msgsnd(g_reqid,&f2,sizeof(userm)-sizeof(long),0);
    //读应答消息队列
    RES buf3;
    msgrcv(g_resid,&buf3,sizeof(buf3),5,0);  //5类消息,转账用
    printf("%s\n",buf3.msg);
    
    
    RES buf4;
    msgrcv(g_resid,&buf4,sizeof(buf4),55,0);  //55类消息,转账用
    printf("%s\n",buf4.msg);
    return;
}
void menu()
{
    
    
    printf("********欢迎来到小黑银行!************\n");
    printf("**************1.开户******************\n");
    printf("**************2.存款******************\n");
    printf("**************3.取款******************\n");
    printf("**************4.查询******************\n");
    printf("**************5.转账******************\n");
    printf("**************6.销户******************\n");
    printf("**************7.退出******************\n");
    
}

Guess you like

Origin blog.csdn.net/Goforyouqp/article/details/132892369