[Sistema operativo Linux] Análisis detallado del código <cliente> del sistema de gestión bancaria basado en la cola de mensajes

Esta es una explicación detallada del código de proyecto para el cliente de un sistema de gestión bancaria basado en colas de información. Introduce principalmente la operación de tareas como apertura de cuenta, depósitos, retiros, etc. en el cliente. El código es relativamente simple, pero cada fragmento de código se explica en detalle. El código fuente proviene principalmente de:
Proyecto de fase de programación del sistema Linux: Sistema de gestión bancaria basado en cola de mensajes.
Este artículo es una explicación detallada basada en su código. También es un registro de mi investigación detallada. después de leer su blog.
Insertar descripción de la imagen aquí


Directorio de artículos


Archivos de encabezado y estructuras.

#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;                 //让客户端从应答消息队列读到的反馈存到这里

función principal

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;

        }
    }
}

La función principal es muy sencilla:

  • Principalmente es un cuerpo de bucle while(1);
  • Luego genere un directorio menu();
  • El usuario ingresa un valor numérico para seleccionar la función a operar, lo correspondiente es la siguiente switchdeclaración de selección;
  • Si el usuario ingresa 1, significa abrir una cuenta y la función correspondiente es Account();
  • Si el usuario ingresa 2, es un depósito y la función correspondiente es Deposit();
  • Si el usuario ingresa 3, significa retiro, y la función correspondiente es Withdrawal();
  • Si el usuario ingresa 4, es una consulta y la función correspondiente es Inquire();
  • Si el usuario ingresa 5, es una transferencia y la función correspondiente es Transfer();
  • Si el usuario ingresa 6, significa cerrar sesión y la función correspondiente es Logout();
  • Si el usuario ingresa 7, saldrá.

El siguiente paso es resolver los problemas de estas funciones paso a paso:


menú

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");
}

Es muy sencillo implementar la función del menú. Solo requiere salida estándar. No es necesario considerar el problema del puerto. El puerto se implementa mediante la siguiente función.


1. Abra una cuenta

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;

}

Explicación del código

Este código es una función del lenguaje C que abre dos colas de mensajes y escribe y lee mensajes de ellas.

Primero, use ftokuna función para generar dos valores clave que identifiquen de forma única la cola de mensajes. ftokLa función requiere una ruta de archivo y un valor entero, y genera un valor clave único basado en estos parámetros.

Luego, use msggetfunciones para abrir la cola de mensajes de solicitud y la cola de mensajes de respuesta. msggetLa función acepta dos parámetros, uno es el valor clave y el otro es la bandera. IPC_CREATIndica que si la cola de mensajes no existe, cree una nueva, 0644lo que indica que el permiso está configurado para leer y escribir.

A continuación, se define una usermvariable de estructura denominada apara almacenar la información de registro del usuario. Luego se solicita al usuario que ingrese el número de identidad, nombre de usuario, contraseña y saldo a través printfde las funciones y scanfrespectivamente, y los valores ingresados ​​por el usuario se almacenan en los campos correspondientes de las variables de estructura a.

aDespués de eso, el campo se establece mtypeen 1, lo que indica que este mensaje es para abrir una cuenta. Luego use msgsndla función para escribir la variable de estructura aen la cola de mensajes de solicitud. msgsndLa función acepta cinco parámetros, que son el ID de la cola de mensajes, el puntero al mensaje, el tamaño del mensaje, el tipo de mensaje y el bit de bandera. El tipo de mensaje aquí es 1, lo que significa que se utiliza para abrir una cuenta.

Finalmente, use msgrcvla función para leer mensajes de la cola de mensajes de respuesta. msgrcvLa función acepta cinco parámetros, que son el ID de la cola de mensajes, el puntero al mensaje, el tamaño del mensaje, el tipo de mensaje y el bit de bandera. El tipo de mensaje aquí es 1, lo que significa que se utiliza para abrir una cuenta. El mensaje leído se almacena en bufuna variable de estructura denominada. Luego use printfla función para imprimir el contenido del mensaje.

El propósito de toda la función es escribir la información de registro del usuario en la cola de mensajes de solicitud, leer los resultados de apertura de cuenta de la cola de mensajes de respuesta e imprimirlos.


2. Depósito

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. Cree el valor clave de la cola de mensajes.

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • ftokLa función se utiliza para generar un valor clave único como identificador para crear una cola de mensajes.
  • El primer parámetro es un nombre de ruta utilizado para generar el valor clave.
  • El segundo parámetro es un número entero utilizado para generar el valor clave.
  • Aquí, se utilizan dos rutas diferentes y números enteros como parámetros para generar dos valores clave diferentes.

2. Abra la cola de mensajes de solicitud.

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • msggetLa función se utiliza para abrir o crear una cola de mensajes.
  • El primer parámetro es el valor clave de la cola de mensajes.
  • El segundo parámetro es una bandera, IPC_CREATlo que significa crear la cola de mensajes si no existe, 0644lo que significa establecer permisos.
  • La función devuelve el identificador de la cola de mensajes, si el valor de retorno es -1, significa que la apertura o creación falló.

3. Abra la cola de mensajes de respuesta.

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice también msggetla función para abrir o crear una cola de mensajes, esta vez utilizando el segundo valor clave.
  • Si la apertura o la creación falla, se imprimirá y devolverá un mensaje de error.

4. Ingrese la información del depósito

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);
  • Cree una estructura nombrada para almacenar información relacionada con el usuario c.userm
  • Ingrese el número de identidad del usuario, nombre de usuario, contraseña y monto del depósito en secuencia.

5. Escriba la solicitud en la cola de mensajes.

c.mtype = 2;   //消息类型为2,存款用
msgsnd(g_reqid,&c,sizeof(userm)-sizeof(long),0);
  • Establezca el tipo de mensaje en 2, lo que indica que se trata de una solicitud de depósito.
  • Utilice msgsndla función para cescribir la estructura en la cola de mensajes de solicitud.
  • sizeof(userm)-sizeof(long)Representa el tamaño del mensaje a enviar, menos longel tamaño del campo de tipo de mensaje.

6. Leer la cola de mensajes de respuesta.

RES buf2;
msgrcv(g_resid,&buf2,sizeof(buf2),2,0);  //2类消息,存款用
printf("%s\n",buf2.msg);
  • Cree una estructura nombrada para recibir el mensaje de respuesta buf2.RES
  • Utilice msgrcvla función para leer mensajes de la cola de mensajes de respuesta.
  • El primer parámetro es el identificador de la cola de mensajes.
  • El segundo parámetro es el buffer para recibir el mensaje.
  • El tercer parámetro es el tamaño del mensaje recibido.
  • El cuarto parámetro es el tipo de mensaje, aquí es 2, indica el mensaje de respuesta para recibir el depósito.
  • El último parámetro es una bandera, 0 indica el comportamiento predeterminado.
  • Imprima el mensaje de respuesta recibido.

7. Regreso

return;
  • Finalizar la ejecución de la función comercial de depósito y regresar al lugar donde fue convocada.

3. Retiro

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. Cree el valor clave de la cola de mensajes.

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • ftokLa función se utiliza para generar un valor clave único como identificador para crear una cola de mensajes.
  • El primer parámetro es un nombre de ruta utilizado para generar el valor clave.
  • El segundo parámetro es un número entero utilizado para generar el valor clave.
  • Aquí, se utilizan dos rutas diferentes y números enteros como parámetros para generar dos valores clave diferentes.

2. Abra la cola de mensajes de solicitud.

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • msggetLa función se utiliza para abrir o crear una cola de mensajes.
  • El primer parámetro es el valor clave de la cola de mensajes.
  • El segundo parámetro es una bandera, IPC_CREATlo que significa crear la cola de mensajes si no existe, 0644lo que significa establecer permisos.
  • La función devuelve el identificador de la cola de mensajes, si el valor de retorno es -1, significa que la apertura o creación falló.

3. Abra la cola de mensajes de respuesta.

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice también msggetla función para abrir o crear una cola de mensajes, esta vez utilizando el segundo valor clave.
  • Si la apertura o la creación falla, se imprimirá y devolverá un mensaje de error.

4. Ingrese la información de retiro

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);
  • Cree una estructura nombrada para almacenar información relacionada con el usuario d.userm
  • Ingrese el número de identidad del usuario, nombre de usuario, contraseña y monto del retiro en secuencia.

5. Escriba la solicitud en la cola de mensajes.

d.mtype = 3;   //消息类型为3,取款用
msgsnd(g_reqid,&d,sizeof(userm)-sizeof(long),0);
  • Establezca el tipo de mensaje en 3, lo que indica que se trata de una solicitud de retiro.
  • Utilice msgsndla función para describir la estructura en la cola de mensajes de solicitud.
  • sizeof(userm)-sizeof(long)Representa el tamaño del mensaje a enviar, menos longel tamaño del campo de tipo de mensaje.

6. Leer la cola de mensajes de respuesta.

RES buf3;
msgrcv(g_resid,&buf3,sizeof(buf3),3,0);  //3类消息,取款用
printf("%s\n",buf3.msg);
  • Cree una estructura nombrada para recibir el mensaje de respuesta buf3.RES
  • Utilice msgrcvla función para leer mensajes de la cola de mensajes de respuesta.
  • El primer parámetro es el identificador de la cola de mensajes.
  • El segundo parámetro es el buffer para recibir el mensaje.
  • El tercer parámetro es el tamaño del mensaje recibido.
  • El cuarto parámetro es el tipo de mensaje, aquí es 3, lo que significa recibir el mensaje de respuesta para el retiro.
  • El último parámetro es una bandera, 0 indica el comportamiento predeterminado.
  • Imprima el mensaje de respuesta recibido.

7. Regreso

return;
  • Finalice la ejecución de la función comercial de retiro y regrese al lugar donde fue convocada.

4. Consulta

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. Cree el valor clave de la cola de mensajes.

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Utilice también ftokla función para generar dos valores clave diferentes para crear colas de mensajes.

2. Abra la cola de mensajes de solicitud.

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice msggetla función para abrir o crear una cola de mensajes de solicitud.

3. Abra la cola de mensajes de respuesta.

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice también msggetla función para abrir o crear una cola de mensajes de respuesta.

4. Ingrese la información de la consulta

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

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

printf("请输入要查询用户的密码!\n");
scanf("%s",e.pw);
  • Cree una estructura nombrada para almacenar información relevante del usuario de la consulta e.userm
  • Ingrese el número de identidad del usuario, nombre de usuario y contraseña en secuencia.

5. Escriba la solicitud en la cola de mensajes.

e.mtype = 4;   //消息类型为4,查询用
msgsnd(g_reqid,&e,sizeof(userm)-sizeof(long),0);
  • Establezca el tipo de mensaje en 4, lo que indica que se trata de una solicitud de consulta.
  • Utilice msgsndla función para eescribir la estructura en la cola de mensajes de solicitud.
  • sizeof(userm)-sizeof(long)Representa el tamaño del mensaje a enviar, menos longel tamaño del campo de tipo de mensaje.

6. Leer la cola de mensajes de respuesta.

RES buf4;
msgrcv(g_resid,&buf4,sizeof(buf4),4,0);  //消息类型为4,查询用
printf("%s\n",buf4.msg);
  • Cree una estructura nombrada para recibir el mensaje de respuesta buf4.RES
  • Utilice msgrcvla función para leer mensajes de la cola de mensajes de respuesta.
  • El primer parámetro es el identificador de la cola de mensajes.
  • El segundo parámetro es el buffer para recibir el mensaje.
  • El tercer parámetro es el tamaño del mensaje recibido.
  • El cuarto parámetro es el tipo de mensaje, aquí es 4, que significa recibir el mensaje de respuesta a la consulta.
  • El último parámetro es una bandera, 0 indica el comportamiento predeterminado.
  • Imprima el mensaje de respuesta recibido.

7. Regreso

return;
  • Finalice la ejecución de la función empresarial de consulta y regrese al lugar donde fue llamada.

5. Transferencia

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. Cree el valor clave de la cola de mensajes.

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Utilice también ftokla función para generar dos valores clave diferentes para crear colas de mensajes.

2. Abra la cola de mensajes de solicitud.

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice msggetla función para abrir o crear una cola de mensajes de solicitud.

3. Abra la cola de mensajes de respuesta.

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice también msggetla función para abrir o crear una cola de mensajes de respuesta.

4. Ingrese la información del usuario de transferencia.

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);
  • Cree dos estructuras nombradas y para almacenar información sobre el usuario que transfiere y el usuario transferido respectivamente f1.f2userm
  • Ingrese el número de identidad del usuario de la transferencia, el nombre de usuario, la contraseña y el monto de la transferencia en secuencia.

5. Escriba la solicitud en la cola de mensajes.

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);
  • Establezca el tipo de mensaje en 5 y 55, lo que indica que estos son dos mensajes para la solicitud de transferencia.
  • Utilice msgsndla función para escribir las estructuras f1y f2en la cola de mensajes de solicitud respectivamente.
  • sizeof(userm)-sizeof(long)Representa el tamaño del mensaje a enviar, menos longel tamaño del campo de tipo de mensaje.

6. Leer la cola de mensajes de respuesta.

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);
  • Cree dos estructuras denominadas y para recibir mensajes de respuesta buf3.buf4RES
  • Utilice msgrcvla función para leer mensajes de la cola de mensajes de respuesta.
  • El primer parámetro es el identificador de la cola de mensajes.
  • El segundo parámetro es el buffer para recibir el mensaje.
  • El tercer parámetro es el tamaño del mensaje recibido.
  • El cuarto parámetro es el tipo de mensaje, aquí 5 y 55 respectivamente, que indica el mensaje de respuesta para recibir la transferencia.
  • El último parámetro es una bandera, 0 indica el comportamiento predeterminado.
  • Imprima el mensaje de respuesta recibido.

7. Regreso

return;
  • Finalice la ejecución de la función comercial de transferencia y regrese al lugar donde fue convocada.

6. Cancelación

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. Cree el valor clave de la cola de mensajes.

key_t kid1,kid2;
kid1 = ftok("/home/whs/002/0706",1); //键值
kid2 = ftok("/home/whs/002/0706",2);
  • Utilice también ftokla función para generar dos valores clave diferentes para crear colas de mensajes.

2. Abra la cola de mensajes de solicitud.

g_reqid = msgget(kid1,IPC_CREAT|0644); //打开请求消息队列
if(g_reqid== -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice msggetla función para abrir o crear una cola de mensajes de solicitud.

3. Abra la cola de mensajes de respuesta.

g_resid =msgget(kid2,IPC_CREAT|0644); //打开应答消息队列
if(g_resid == -1)
{
    
    
    perror("msgget");
    return;
}
  • Utilice también msggetla función para abrir o crear una cola de mensajes de respuesta.

4. Ingrese la información del usuario para cerrar sesión.

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);
  • Cree una estructura nombrada bpara usermalmacenar información sobre los usuarios desconectados.
  • Ingrese el número de identidad, nombre de usuario, contraseña y saldo del usuario a cerrar sesión en secuencia.

5. Escriba la solicitud en la cola de mensajes.

b.mtype = 6;   //消息类型为6,注销用
msgsnd(g_reqid,&b,sizeof(userm)-sizeof(long),0);
  • Establezca el tipo de mensaje en 6, lo que indica que se trata de un mensaje de solicitud de cierre de sesión.
  • Utilice msgsndla función para bescribir la estructura en la cola de mensajes de solicitud.
  • sizeof(userm)-sizeof(long)Representa el tamaño del mensaje a enviar, menos longel tamaño del campo de tipo de mensaje.

6. Leer la cola de mensajes de respuesta.

RES buf1;
msgrcv(g_resid,&buf1,sizeof(buf1),6,0);  //6类消息,注销用
printf("%s\n",buf1.msg);
  • Cree una estructura nombrada buf1para RESrecibir el mensaje de respuesta.
  • Utilice msgrcvla función para leer mensajes de la cola de mensajes de respuesta.
  • El primer parámetro es el identificador de la cola de mensajes.
  • El segundo parámetro es el buffer para recibir el mensaje.
  • El tercer parámetro es el tamaño del mensaje recibido.
  • El cuarto parámetro es el tipo de mensaje, aquí es 6, lo que significa recibir el mensaje de respuesta de cierre de sesión.
  • El último parámetro es una bandera, 0 indica el comportamiento predeterminado.
  • Imprima el mensaje de respuesta recibido.

7. Regreso

return;
  • Finalice la ejecución de la función comercial de cierre de sesión del usuario y regrese al lugar donde fue llamada.

código general

#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");
    
}

Supongo que te gusta

Origin blog.csdn.net/Goforyouqp/article/details/132892369
Recomendado
Clasificación