[Linux] IPC : Message Queue 메시지 대기열 방식 데이터 전달 Sample Source, Example

Posted by [하늘이]
2016. 11. 29. 18:04 IT/Linux
반응형


이번에는 두개의 Application 간에 message queue 방식의 데이터 전송 예제이다.

지난번에는 Shared Memory 방식이였으나 그 방식은 Server쪽이 반복적으로 Polling 을 하고 있어 비효율적이였다.

Msg Queue 통신과 Shared Memory Server 쪽에 Signal wait을 사용하면 좀더 효율적으로 사용할 수 있을 것으로 판단된다.


Left : Server / Right : Client


API 참조 링크

msgget() : http://forum.falinux.com/zbxe/index.php?_filter=search&mid=C_LIB&search_target=title&search_keyword=msgget&document_srl=420147

[위 링크를 보면 아래 사용한 msg queue 관련 api 내용이 있다.]



Sample Source

TestEclipsProjectMsgQueue.tar.gz




Sample Source

Server 측

testIpcMsgQueue.h

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef TESTIPCMSGQUEUE_H_
#define TESTIPCMSGQUEUE_H_
 
#define TEXT_SIZE 2048
#define KEY_ID_MSG_QUEUE 2017
 
struct msg_queue_st {
    long int msgType;
    char data[TEXT_SIZE];
};
 
#endif /* TESTIPCMSGQUEUE_H_ */
 
cs


Test_IPC_MsgQueue_Server.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
 
#include "testIpcMsgQueue.h"
 
using namespace std;
 
int main() {
 
    int running = 1;
    int msgID = 0;
    struct msg_queue_st msgQueueData;
    long int msg_to_receive = 0;
 
    msgID = msgget((key_t)KEY_ID_MSG_QUEUE, 0666 | IPC_CREAT);
 
    if(msgID == -1){
        cout << "[Server][Error]msgget fail. id:" << msgID << endl;;
        exit(EXIT_FAILURE);
    }
    else{
        while(running){
            cout << "[Server]Waiting data from client."<< endl;
            if(msgrcv(msgID, (void*)&msgQueueData, TEXT_SIZE, msg_to_receive, 0== -1){
                cout << "[Server][Error]msgrcv fail. error:" << errno << endl;;
                exit(EXIT_FAILURE);
            }
            cout << "[Server]echo Msg data:" << msgQueueData.data << endl;
 
            if (strncmp(msgQueueData.data, "end"3== 0) {
                running = 0;
            }
        }
 
        if(msgctl(msgID, IPC_RMID, 0== -1){
            cout << "[Server][Error] msgctl IPC_RMID fail."<< endl;;
            exit(EXIT_FAILURE);
        }
 
    }
 
    exit(EXIT_SUCCESS);
    //return 0;
}
 
cs


Client 측

Test_IPC_MsgQueue_Client.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
 
#include "testIpcMsgQueue.h"
 
using namespace std;
 
int main() {
 
    int running = 1;
    int msgID = 0;
    struct msg_queue_st msgQueueData;
    char userData[TEXT_SIZE];
 
    msgID = msgget((key_t)KEY_ID_MSG_QUEUE, 0666 | IPC_CREAT);
 
    if(msgID == -1){
        cout << "[Client][Error]msgget fail. id:" << msgID << endl;;
        exit(EXIT_FAILURE);
    }
    else{
        while(running){
 
            cout << "[Client]Enter text :"<< endl;
            fgets(userData, TEXT_SIZE, stdin);
 
            msgQueueData.msgType = 1;
            strcpy(msgQueueData.data, userData);
 
            if(msgsnd(msgID, (void*)&msgQueueData, TEXT_SIZE, 0== -1){
                cout << "[Client][Error]msgQueueData fail. error:" << errno << endl;;
                exit(EXIT_FAILURE);
            }
 
            if (strncmp(msgQueueData.data, "end"3== 0) {
                running = 0;
            }
        }
    }
 
    exit(EXIT_SUCCESS);
    //return 0;
}
 
cs


반응형