#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgget(key_t key, int msgflg);
: Message queue ID를 구하는 함수. 옵션에 따라 생성도 가능파라미터
• key: IPC object Key or IPC_PRIVATE
‐ IPC_PRIVATE: 지정 시 새로운 message queue ID 생성 • msgflg: permission + mask
‐ IPC_CREAT: key에 매치되는 message queue ID 없으면 생성
‐ IPC_EXCL: key에 매치되는 message queue ID가 있으면 에러 발생
반환값
• 성공: message queue ID
• 실패: -1
key_t ftok(const char *pathname, int proj_id);
: ipc key 값을 구하는 함수파라미터
• pathname
‐ 조합할 파일 경로
‐ 파일이 존재해야 하고, readable해야 함
• proj_id
- 임의의 project ID (int 형이여야 함)
반환값
• 성공: IPC Key
• 실패: -1
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
: 메세지 전송 함수파라미터
• msqid: message queue id
• msgq: 전송할 메시지 버퍼
• msgsz: 전송 메시지 사이즈(mtext의 길이, in bytes)
• msgflg
‐ IPC_NOWAIT: non-blocking I/O
반환값
• 성공: 0
• 실패: -1
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
: 메세지 수신 함수파라미터
msqid: message queue id
msgp: message 수신 버퍼
msgsz: 최대 수신 길이(mtext의 길이, in bytes) msgtyp: 수신할 message type
‐ 0: 첫번째 메시지 수신
‐ 양수: msgtype에 매치되는 첫번째 메시지 수신
‐ 음수: 지정된 절대값보다 작거나 같은 msgtype에 매치되는 첫번째 메시지 수신
msgflg
‐ IPC_NOWAIT: non-blocking I/O
‐ MSG_COPY
▫ n번째 메시지를 복사해서 수신(msgtyp이 index로 사용됨)
▫ 반드시 IPC_NOWAIT와 같이 사용해야 함
‐ MSG_EXCEPT: msgtyp과 매치되지 않는 메시지를 수신
‐ MSG_NOERROR: 메시지 사이즈가 msgsz보다 크다면 truncate 시킴
반환값
• 성공: 실제로 받은 데이터 길이(mtext의 길이, in bytes)
• 실패: -1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
: message queue 제어 함수파라미터
• msqid: message queue id • cmd
‐ IPC_STAT: kernel의 msgid_ds 정보 습득
‐ IPC_SET: kernel의 msgid_ds에 설정
‐ IPC_RMID: message queue 제거
• buf
반환값
• 성공: 0
• 실패: -1
struct msqid_ds {
struct ipc_perm msg_perm; /* permission에 대한 정보가 있는 변수 */
time_t msg_stime; /* 가장 최근에 send를 한 시간 */
time_t msg_rtime; /* 가장 최근에 recv를 한 시간 */
time_t msg_ctime; /* 가장 최근에 변경된 시간 */
unsigned long __msg_cbytes; /* message queue의 max byte */
msgqnum_t msg_qnum; /* queue에 있는 메시지 개수 */
msglen_t msg_qbytes; /* queue에서 허용하는 메시지의 최대 개수 */
pid_t msg_lspid; /* 마지막으로 send한 프로세스의 pid*/
pid_t msg_lrpid; /* 마지막으로 recv한 프로세스의 pid */
};
struct ipc_perm {
key_t __key; /* Key supplied to msgget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define SHARED_PATH "/home/alwns28/example_folder/sysv_example/pw_file"
#define PROJ_ID 1234
#define MAX_BUF_LEN 1024
typedef struct msgbuf {
long mtype;
char mtext[MAX_BUF_LEN];
} SYSV_BUF;
static void print_help(char *program_name)
{
printf("Usage: %s (s mtype |r mtype)\n", program_name);
}
SYSV_BUF sysv_buf_setting(const char *msg, long mtype)
{
SYSV_BUF buf;
memset((void *)&buf, 0, sizeof(SYSV_BUF));
strcpy(buf.mtext, msg);
buf.mtype = mtype;
return buf;
}
static int sysv_mqid_setting(int *mq_id)
{
/* Gen ipc key */
key_t key;
printf(" = Create IPC key ");
key = ftok(SHARED_PATH, PROJ_ID);
if(key == -1){
printf(" => FAIL \n");
perror("ftok()");
return -1;
}
printf(" => SUCCESS, key: %d\n", key);
printf(" = Create Message Queue ID ");
*mq_id = msgget(key, IPC_CREAT);
if(*mq_id == -1){
printf(" => FAIL \n");
perror("msgget()");
return -1;
}
printf(" => SUCCESS, ID: %d\n", *mq_id);
return 0;
}
int send_data(long mtype){
int mq_id;
char buf[MAX_BUF_LEN];
SYSV_BUF mq_buf;
if(sysv_mqid_setting(&mq_id) == -1){
printf("FAIL setting mq id\n");
return -1;
}
memset((void *)buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "Hello world");
mq_buf = sysv_buf_setting(buf, mtype);
printf(" = Send Message [%s] ", mq_buf.mtext);
if(msgsnd(mq_id, (const void *)&mq_buf, sizeof(mq_buf.mtext), 0) == -1){
printf(" => FAIL \n");
perror("msgsnd()");
return -1;
}
printf(" => SUCCESS \n");
return 0;
}
int recv_data(long mtype){
int mq_id;
SYSV_BUF mq_buf;
/* Gen ipc key */
if(sysv_mqid_setting(&mq_id) == -1){
printf("FAIL setting mq id\n");
return -1;
}
if(msgrcv(mq_id, (void *)&mq_buf, sizeof(mq_buf.mtext), mtype, 0) == -1){
printf(" => FAIL \n");
perror("msgrcv()");
return -1;
}
printf(" = Recv Messagae => SUCCESS , Recv Data: %s\n", mq_buf.mtext);
return 0;
}
int main(int argc, char **argv)
{
long mtype;
if(argc < 3){
print_help(argv[0]);
return -1;
}
int fd = open(SHARED_PATH, O_CREAT, 0644);
close(fd);
mtype = strtol((const char *)argv[2],NULL,10);
if(!strcmp(argv[1], "s")){
if(send_data(mtype) == -1){
printf("메세지 전송을 실패하였습니다.\n");
return -1;
}
}else if(!strcmp(argv[1], "r")) {
if(recv_data(mtype) == -1){
printf("메세지 수신을 실패하였습니다.\n");
return -1;
}
} else {
print_help(argv[0]);
}
return 0;
}