반응형

msgrcv(2)

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

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msqid Message Queue ID로 부터 데이터 수신합니다. 

전송/수신하는 데이터는 아래와 같은 형태로 구성해야합니다. 구조체 이름 및 format은 마음대로 정의할 수 있으며, 첫번째를 long type을 선언하기만 하면 됩니다.

 

struct msgbuf 
{
   long mtype;       /* message type, must be > 0 */
   char mtext[];     /* message data */
};

예)
/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];
	......
};

struct my_msgbuf {
   long mtype;          /* message type, must be > 0 */
   struct my_data body; /* message data */
};

-----------------------------
또는 

struct my_msgbuf {
   long mtype;          /* message type, must be > 0 */
   char data1[100];
	......
};

 

파라미터

msqid
    - msgget(2)가 return한 Message Queue ID 
msgp
    - 수신한 데이터를 저장할 buffer


수신하는 데이터는 아래와 같은 형태로 구성해야합니다.
구조체 이름 및 format은 마음대로 정의할 수 있으며, 첫번째를 long type을 선언하기만 하면 됩니다.

struct msgbuf 

{
   long mtype;       /* message type, must be > 0 */
   char mtext[];     /* message data */
   ......
};

예)
/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];

	......

};

struct my_msgbuf {
   long mtype;          /* message type, must be > 0 */
   struct my_data body; /* message data */
};
msgsz
    - 수신하려는 데이터의 크기이며, 저장할 buffer의 최대크기로 설정합니다.
msgtyp
    - 수신할 Message type

 0    : 아무 message type이든 queue에 저장된 첫번째 message를 수신합니다.
 
 양수 : message type이 일치하는 첫번째 message를 수신함. 
       msgflg가 MSG_EXECPT이면 message type이 일치하지 않는 message를 수신합니다.
       
 음수 : msgtyp의 절대값보다 같거나 작은 message type중에서 message type이 
       가장 작은 message 부터 수신합니다.
msgflg
    - msgflg는 0 또는 아래의 상수에 대해서 bit or 연산으로 조합할 수 있습니다.

 IPC_NOWAIT : 수신할 메시지가 없으면 errno에 ENOMSG를 설정하고 -1을 return 합니다.
              IPC_NOWAIT가 설정되지 않았으면, 데이터를 수신할 수 있을 때까지 block됩니다.

 MSG_EXCEPT : msgtyp이 0보다 크면 message type이 일치하지 않는 message를 수신합니다.

 MSG_NOERROR : msgsz보다 데이터의 크기가 클 경우에는 데이터를 msgsz만큼만 읽고 truncate합니다.
              MSG_NOERROR가 설정되지 않았으면, 
              msgsz보다 데이터의 크기가 크면 E2BIG 오류가 발생합니다.

 

RETURN

0 이상
    - 실제로 읽은 데이터의 크기를 return 합니다.
      return된 크기에는 long mtype 크기를 뺀 크기입니다. 
      
-1
    - 오류가 발생하였으며, 상세한 오류는 errno에 저장됩니다.

 E2BIG  : msgflg가 MSG_NOERROR로 설정되지 않았으며, 읽으려는 message가 msgsz)보다 큽니다.
 EACCES : Message queue에 대한 읽기 권한이 없습니다.
 EAGAIN : msgflg가 IPC_NOWAIT이면서 Message Queue에 쌓인 Message가 없습니다.
 EFAULT : msgp가 유효하지 않은 메모리 번지입니다.
 EIDRM  : msqid가 이미 삭제된 ID입니다.
 EINTR  : message queue로 전달중 signal이 발생하여 전달에 실패하였습니다.
 EINVAL : msqid가 유효하지 않거나, msgsz가 0보다 작습니다. 
 ENOMSG : msgflg가 IPC_NOWAIT로 설정되어 있으며 요청한 message type의 message가 없습니다.

 


활용 예제

 

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

/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];
    /*
        ......
    */
};

struct msgbuf 
{
   long mtype;
   struct my_data body;
};


int main(int argc, char *argv[])
{
   int qid;
   int msgtype = 1;
   int msgkey;
   struct msgbuf msg;
   char send_data[100];
   char dir[256];

   /* Message Queue의 key를 생성합니다. */
   snprintf(dir, 256, "%s/msg_home", getenv("HOME"));
   msgkey = ftok(dir, 'M');

   /* Message Queue를 생성합니다. */
   if((qid = msgget(msgkey, IPC_CREAT | 0666)) == -1) {
       perror("msgget error");
	   return 1;
   }

   memset(&msg, 0x00, sizeof(msg));

   /* message queue data 수신합니다. */
   if (msgrcv(qid, (void *) &msg, sizeof(struct msgbuf), msgtype, MSG_NOERROR | IPC_NOWAIT) == -1) {
       if (errno != ENOMSG) {
           perror("msgrcv error");
           exit(1);
       }
   }

   /* 수신 데이터 처리 로직.... */

   ......
   
   return 0;
}

 

반응형
블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

,