1

我正在学习 IPCS,我尝试将消息从客户端发送到服务器,服务器将其乘以 2,然后使用 、 、 和 将其发送ftokmsgget客户端。这是我的代码:msgrcvmsgsndmsgctl

ex1.h

#ifndef EX1_H
#define EX1_H

#define ID 2
#define PATH "./client.c"
struct msgbuf{
  long mtype;
  int mvalue;
} message, retour;
key_t cle;
int mes_id;
#endif

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "ex1.h"

int main (int argc, char **argv){
  if((cle=ftok(PATH,ID)) == (key_t)-1){
    perror("Erreur lors de la création de la clé ");
    exit(EXIT_FAILURE);
  }
  if((mes_id = msgget(cle,IPC_CREAT | 0660 | IPC_EXCL)) == -1){
    perror("Erreur dans la création de la file de message ");
    exit(EXIT_FAILURE);
  }
  message.mtype = 1;
  if((msgrcv(mes_id, &message, sizeof(message), 1, 0)) == -1){
    perror("Erreur lors de la récéption du message ");
    exit(EXIT_FAILURE);
  }
  printf("Je suis le serveur et j'ai reçu %d.\n",message.mvalue);
  printf("J'effectue ma multiplication par 2 et renvoie le résultat.\n");
  retour.mtype = 3;
  retour.mvalue = message.mvalue * 2;
  if((msgsnd(mes_id, &retour, sizeof(retour), 0)) == -1){
    perror("Erreur lors de l'envoi du résultat ");
    exit(EXIT_FAILURE);
  }
  sleep(1);
  msgctl(mes_id,IPC_RMID, NULL);
  return EXIT_SUCCESS;
}

客户端.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "ex1.h"
#include <unistd.h>
int main (int argc, char **argv){
  if((cle=ftok(PATH, ID)) == (key_t)-1){
    perror("Erreur lors de la création de la clé ");
    exit(EXIT_FAILURE);
  }
  if((mes_id = msgget(cle, 0660 | IPC_EXCL)) == -1){
    perror("Erreur lors de la récupération du numéro de la file ");
    exit(EXIT_FAILURE);
  }
  message.mtype = 1;
  message.mvalue = 4;
  if((msgsnd(mes_id, &message, sizeof(message), 0)) == -1){
    perror("Erreur lors de l'envoi du message ");
    exit(EXIT_FAILURE);
  }
  retour.mtype = 3;
  sleep(2);
  if((msgrcv(mes_id, &retour, sizeof(retour), 3, 0)) == -1){
    perror("Erreur lors de la récéption du résultat ");
    exit(EXIT_FAILURE);
  }
  printf("Je suis le client et j'ai reçu %d\n", retour.mvalue);
  return EXIT_SUCCESS;
}

由于第 23/24 行,我得到Invalid argumentIdentifier removed错误,但我不明白这里有什么问题。

4

1 回答 1

0

msgsnd()/msgrcv()的“大小”参数

msgsnd()msgrcv()接收消息数据部分的大小(不包括类型字段)。这应该像这样使用:

struct msgbuf{
  long mtype;
  int mvalue;
} message, retour;
[...]
msgrcv(mes_id, &retour, sizeof(retour.mvalue), 3, 0));
[...]
msgsnd(mes_id, &message, sizeof(message.mvalue), 0);

有关更多详细信息,请查看msgrcv()msgsnd()手册中的示例部分。

调用sleep()

在服务器/客户端消息交换期间抑制对sleep()的调用,因为它们是同步的:当一个发送消息时,另一个等待接收。当您在最后一次“接收”之前在客户端中调用sleep(2)时,当它唤醒时,服务器可能已经删除了消息队列。对于您的示例,只需在队列销毁之前在服务器末尾放置一个sleep()即可。

于 2020-11-26T12:24:10.117 回答