Идентификатор очереди сообщений изменяется - PullRequest
0 голосов
/ 10 декабря 2018

Я попытался реализовать простое взаимодействие сервер-клиент между двумя процессами.У меня проблемы с сервером, в котором есть две очереди сообщений.

Проблема в том, что идентификатор очереди сообщений для второй очереди каким-то образом изменяется сразу после вызова msgrcv для первой очереди.

Пожалуйста, рассмотрите упрощенную версию (в демонстрационных целях) моего серверного процесса ниже:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define SERVER_KEY_PATHNAME "/student/m18512/m1851201/mqueue_server_key"
#define USERS_KEY_PATHNAME "/student/m18512/m1851201/labs"
#define PROJECT_ID 'M'
#define PROJECT_ID_U 'U'
#define QUEUE_PERMISSIONS 0660


struct buffer {
    int qid_a;
    char message_text [200];
    char dest_user[30];
};

struct message {
    long mtype;
    struct buffer buffer;
};

struct buffer_user {
    char source_user [30];
    long qid_source_user;
};

struct message_user {
    long mtype;
    struct buffer_user buffer_user;
};

int main (int argc, char **argv)
{
    setvbuf(stdout, NULL, _IONBF, 0);
    key_t queue_a_key, queue_b_queue;
    int qid_a, qid_b;
    struct message message;
    struct msqid_ds buf;

    //Create queue A
    if ((queue_a_key = ftok (SERVER_KEY_PATHNAME, PROJECT_ID)) == -1) {
        perror ("ftok");
        exit (1);
    }
    if ((qid_a = msgget (queue_a_key, IPC_CREAT | QUEUE_PERMISSIONS)) == -1) {
        perror ("msgget");
        exit (1);
    }

    //Create queue B
    if ((queue_b_queue = ftok (USERS_KEY_PATHNAME, PROJECT_ID_U)) == -1) {
        perror ("ftok");
        exit (1);
    } 
    if ((qid_b = msgget (queue_b_queue, IPC_CREAT | QUEUE_PERMISSIONS)) == -1) {
        perror ("msgget");
        exit (1);
    }


    while (1) { 
        printf("Step 1: qid A: %d\n", qid_a);
        printf("Step 1: qid B: %d\n", qid_b);

        // read an incoming message
        if (msgrcv (qid_a, &message, 300, 0, 0) == -1) {
            perror ("msgrcv");
            exit (1);
        }

        printf("Step 2: qid A: %d\n", qid_a);
        printf("Step 2: qid B: %d\n", qid_b);

    }
}

Как видно из выходных данных, как только клиентский процесс отправляет сообщение в очередь A,идентификатор для очереди B изменен:

Step 1: qid A: 1674706969
Step 1: qid B: 1679229087
Step 2: qid A: 1674706969
Step 2: qid B: 1679229013

Исходный идентификатор для очереди B - 1679229087 (шаг 1), но на шаге 2 идентификатор для этой очереди становится 1679229013.

Более того, глядя на ipcs, я не вижу очереди с новым идентификатором 1679229013, но 1679229087 все еще существует.

Пожалуйста, см. Ниже также упрощенный код для клиентского процесса:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define SERVER_KEY_PATHNAME "/student/m18512/m1851201/mqueue_server_key"
#define USERS_KEY_PATHNAME "/student/m18512/m1851201/labs"
#define PROJECT_ID 'M'
#define PROJECT_ID_U 'U'

struct buffer {
    int qid;
    char message_text [200];
    char dest_user[30];
};

struct message {
    long mtype;
    struct buffer buffer;
};

struct buffer_user {
    char source_user [30];
    long qid_source_user;
};

struct message_user {
    long mtype;
    struct buffer_user buffer_user;
};


int main (int argc, char **argv)
{
    setvbuf(stdout, NULL, _IONBF, 0);
    struct message my_message, return_message;
    my_message.mtype = 1;   
    key_t server_queue_key, users_queue_key;
    int server_qid, myqid, users_qid;

    // create my client queue for receiving messages from server
    if ((myqid = msgget (IPC_PRIVATE, 0660)) == -1) {
        perror ("msgget: myqid");
        exit (1);
    }
    if ((server_queue_key = ftok (SERVER_KEY_PATHNAME, PROJECT_ID)) == -1) {
        perror ("ftok");
        exit (1);
    }
    if ((server_qid = msgget (server_queue_key, 0)) == -1) {
        perror ("msgget: server_qid");
        exit (1);
    }

    my_message.buffer.qid = myqid; 

    printf("Server qid %d, my qid %d\n", server_qid, myqid);

    printf ("Please type a message: ");

    while (fgets (my_message.buffer.message_text, 198, stdin)) {
        // remove newline from string
        int length = strlen (my_message.buffer.message_text);
        if (my_message.buffer.message_text [length - 1] == '\n')
           my_message.buffer.message_text [length - 1] = '\0';

        // send message to server
        if (msgsnd (server_qid, &my_message, sizeof (my_message) + 1, 0) == -1) {
            perror ("client: msgsnd");
            exit (1);
        }

    }
    exit (0);
}

EDIT : Кажется, проблема существует, когда я объявляю идентификаторы очереди следующим образом:

int qid_a, qid_b;

Однако, когда я объявляю их так:

int qid_a = 0, qid_b = 0

Проблема исчезает.Почему это может быть?

...