我试图在两个进程之间实现简单的服务器 - 客户端通信 . 我在服务器进程中遇到有2个消息队列的问题 .
问题是第二个队列的消息队列ID在第一个队列的 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的id就会改变:
Step 1: qid A: 1674706969
Step 1: qid B: 1679229087
Step 2: qid A: 1674706969
Step 2: qid B: 1679229013
队列B的原始id是 1679229087
(步骤1),但是在步骤2,该队列的id变为 1679229013
.
此外,看着ipcs,我没有看到一个带有新id 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 :当我像这样声明队列ID时,似乎存在问题:
int qid_a, qid_b;
但是,当我这样声明它们时:
int qid_a = 0, qid_b = 0
问题消失了 . 为什么会这样?