首页 > 解决方案 > 为多个客户端设计一个 Unix 消息队列服务器

问题描述

为了使一台服务器和多个客户端仅使用一个消息队列,我应该在以下代码中进行哪些修改。我很确定我需要分配不同的值msgid,然后使用它从消息队列中获取消息,但不完全确定我是否正确以及如何实现它。如果有任何帮助,我将不胜感激。

代码1:

struct my_msg_st { 
     long int my_msg_type; 
     char some_text[BUFSIZ];
};

int main() {
    int running = 1;
    int msgid;
    struct my_msg_st some_data; 
    long int msg_to_receive = 0

    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

    if (msgid == -1) {
         fprintf(stderr, “msgget failed with error: %d\n”, errno);
         exit(EXIT_FAILURE);
    }

    while(running) {
        if (msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) {
              fprintf(stderr, “msgrcv failed with error: %d\n”, errno); 
              exit(EXIT_FAILURE);
        }
        printf(“You wrote: %s”, some_data.some_text);
        if (strncmp(some_data.some_text, “end”, 3) == 0) {
              running = 0;
        }
    }

    if (msgctl(msgid, IPC_RMID, 0) == -1) { 
        fprintf(stderr, “msgctl(IPC_RMID) failed\n”);         
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS); 
}

代码 2:

#define MAX_TEXT 512

struct my_msg_st {
     long int my_msg_type; char some_text[MAX_TEXT];
};

int main() {
     int running = 1;
     struct my_msg_st some_data; int msgid;
     char buffer[BUFSIZ];
     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

     if (msgid == -1) {
           fprintf(stderr, “msgget failed with error: %d\n”, errno);         
           exit(EXIT_FAILURE);
     }

     while(running) {
           printf(“Enter some text: “); 
           fgets(buffer, BUFSIZ, stdin); 
           some_data.my_msg_type = 1; 
           strcpy(some_data.some_text, buffer); 

           if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) {          
                 fprintf(stderr, “msgsnd failed\n”);
                 exit(EXIT_FAILURE);
           }

           if (strncmp(buffer, “end”, 3) == 0) {
                 running = 0;
           }

     }
     exit(EXIT_SUCCESS); 
 }

标签: cipcsysv-ipc

解决方案


我建议您创建一个队列,并且您推送到队列的每条消息都应该具有不同的 my_msg_type 值,而不是像您所做的那样将其硬编码为 1。这是客户端和服务器之间的映射。每个客户端可以从 1 到 n 编号。

some_data.my_msg_type = client_id;

在每个客户端中完成此操作后,您可以使用相应的客户端 ID 调用 msgrcv。这可以通过使用客户端 ID 作为 msgrcv 中的第四个参数来完成。

msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, client_id)

这样,您就有了一个为多个客户端生成数据的服务器。

希望有帮助!


推荐阅读