消息队列IPC无法正常工作

问题描述 投票:0回答:1

此代码使用 C 中的消息队列实现了一个简单的客户端-服务器通信系统。

local.h

#include <stdio.h>
#include <sys/types.h>
#include "sys/ipc.h"
#include <sys/msg.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

#define SEED 'g'    /* seed for ftok */
#define SERVER 1L   /* message for the server */

typedef struct{
    long    msg_to; /* placed in the queue for */
    long    msg_fm;  /* placed in the queue by */
    char    buffer[BUFSIZ];
}MESSAGE;

client.c:

#include "local.h" 

int main(int argc, char const *argv[])
{
    key_t       key;
    pid_t       cli_pid;
    int         mid, n;
    MESSAGE     msg;
    static char m_key[10];

    cli_pid = getpid();
    
    if((key = ftok(".", SEED)) == -1){
        perror("Client: key generation");
        exit(1);
    }

    if((mid = msgget(key, 0)) == -1){
        mid = msgget(key, IPC_CREAT | 0660);
        printf("%d", mid);
        
        switch (fork()){
        case -1:
            perror("Client: fork");
            exit(3);
        case 0:
            sprintf(m_key, "%d", mid);
            execlp("./server", "server", m_key, NULL);
            perror("Client: exec");
            exit(4);
        }
    }
    while(1){
        msg.msg_to = SERVER;
        msg.msg_fm = cli_pid;

        write(fileno(stdout), "cmd>", 5);
        memset(msg.buffer, 0x0, BUFSIZ);
        n = read(fileno(stdin), msg.buffer, BUFSIZ);
        if(n == 0){
            break;
        }


        if(msgsnd(mid, &msg, sizeof(msg), 0) == -1){
            perror("Client: msgsend");
            exit(5);
        }
        if((n = msgrcv(mid, &msg, sizeof(msg), cli_pid, 0)) != -1){
            write(fileno(stdout), msg.buffer, strlen(msg.buffer));
        }
    }
    msgsnd(mid, &msg, 0, 0);
    exit(0);
}

服务器.c:

#include "local.h"

int main(int argc, char const *argv[])
{
    int     mid, n;
    MESSAGE msg;
    void    process_msg(char *, int);

    if (argc != 3) {
        fprintf(stderr, "Usage: %s msq_id &\n", argv[0]);
        exit(1);
    }
    while (1) {
        if ((n=msgrcv(mid, &msg, sizeof(msg), SERVER, 0)) == -1 ) {
            perror("Server: msgrcv");
            exit(2);
        } else if (n == 0){
            break;
        } else {
            process_msg(msg.buffer, strlen(msg.buffer));
            msg.msg_to = msg.msg_fm;
            msg.msg_fm = SERVER;
            if (msgsnd(mid, &msg, sizeof(msg), 0) == -1 ) {
                perror("Server: msgsnd");
                exit(3);
            }
        }
    }
    msgctl(mid, IPC_RMID, (struct msqid_ds *) 0 );
    exit(0);
}

void process_msg(char *b, int len) {
    int i;
    for (i = 0; i < len; ++i){
        if (isalpha(*(b + i))){
            *(b + i) = toupper(*(b + i));
        }
    }
}

如果我尝试使用以下命令编译这些文件:

gcc -o 服务器server.c
gcc -o 客户端 client.c

并运行文件:

./服务器 123 &
./客户

服务器正在运行并等待,

(基本)用户@PC:~/UNIX/mqueues$ ./server 123 &
[2]93463
(基本)user@PC:~/UNIX/mqueues$ 用法:./server msq_id &
/在此等待消息/

然后我尝试从客户端发送消息。但是我从客户端收到错误消息:

(基本)用户@PC:~/UNIX/mqueues$ ./client
cmd>你好
客户端:msgsend:参数无效

我可能做错了什么,如果你能帮助我,我将非常感激。谢谢。

c unix posix ipc message-queue
1个回答
0
投票

在下面的代码行中,msg_to 未设置为 SERVER。这似乎是个问题。

            process_msg(msg.buffer, strlen(msg.buffer));

            msg.msg_to = msg.msg_fm;

            msg.msg_fm = SERVER;

如果未设置 msg_to,则 msg_type 对于 msgsend() 调用无效,并且可能会失败。

© www.soinside.com 2019 - 2024. All rights reserved.