Saturday, September 26, 2020

Message Queue - message types reception

Consider this the extension of the previous post on Message Queue.  We will see how we can retrieve messages of different types.

Write2.c

 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
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
	long mtype;
	char mtext[20];
} mymsg;

int main()
{
	key_t key;
	int msgid;
	
	key=ftok("dummy.txt",65);
	msgid = msgget(key,0666 | IPC_CREAT);
	printf("Key - %x ;MessageId - %d \n",key,msgid);

	mymsg.mtype = 1;	
	strcpy(mymsg.mtext,"its my world 1 \0");
	msgsnd(msgid,&mymsg,strlen(mymsg.mtext),0);	
	printf("Sent Type: %d Data: %s\n",mymsg.mtype,mymsg.mtext);

	mymsg.mtype = 2;	
	strcpy(mymsg.mtext,"its my world 2 \0");
	msgsnd(msgid,&mymsg,strlen(mymsg.mtext),0);	
	printf("Sent Type: %d Data: %s\n",mymsg.mtype,mymsg.mtext);
	
	mymsg.mtype = 3;	
	strcpy(mymsg.mtext,"its my world 3 \0");
	msgsnd(msgid,&mymsg,strlen(mymsg.mtext),0);	
	printf("Sent Type: %d Data: %s\n",mymsg.mtype,mymsg.mtext);
	
	mymsg.mtype = 4;	
	strcpy(mymsg.mtext,"its my world 4 \0");
	msgsnd(msgid,&mymsg,strlen(mymsg.mtext),0);	
	printf("Sent Type: %d Data: %s\n",mymsg.mtype,mymsg.mtext);
	
	return 0;
}

We have created message queue, and passing 4 messages of different types 1,2,3 and 4.

Read2.c

 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
#include<stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

struct msgbuf {
	long mtype;
	char mtext[20];
} mymsg;

int main(int argc, char *argv[])
{
	key_t key;
	int msgid;
	int type;
	type = atoi(argv[1]);

	key=ftok("dummy.txt",65);
	msgid=msgget(key,0644);
	printf("Key - %x ;MessageId - %d \n",key,msgid);
	
	while (1)
	{			
		msgrcv(msgid,&mymsg,sizeof(mymsg),type,IPC_NOWAIT);
		if (errno == ENOMSG) {
			printf("No messages\n");
			break;
		} else {
			printf("Received Data,%s\n",mymsg.mtext);
			printf("Received Data type, %d\n\n",mymsg.mtype);
		}
	}
	return 0;
}
  • Line 16 - Passing the 'message type' as command line argument
  • Line 22 - We run the while loop to receive all the messages available with the mentioned message type.
  • Line 24 - The last argument IPC_NOWAIT is used to instruct 'msgrcv' to return immediately if there is no message present in queue.  'errno' will be set with 'ENOMSG' when this happens.

Demonstration

For different values of msgtypes, the msgrcv behave accordingly

Positive: Picks the first message in the queue corresponding to this type

 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
[root@msgq]# ./write2
Key - 41014da0 ;MessageId - 327680
Sent Type: 1 Data: its my world 1
Sent Type: 2 Data: its my world 2
Sent Type: 3 Data: its my world 3
Sent Type: 4 Data: its my world 4

[root@msgq]# ./read2 3
Key - 41014da0 ;MessageId - 327680
Received Data,its my world 3
Received Data type, 3

No messages

[root@msgq]# ./read2 3
Key - 41014da0 ;MessageId - 327680
No messages

[root@msgq]# ./read2 2
Key - 41014da0 ;MessageId - 327680
Received Data,its my world 2
Received Data type, 2

No messages

[root@msgq]# ./read2 4
Key - 41014da0 ;MessageId - 327680
Received Data,its my world 4
Received Data type, 4

No messages
  • Line 1-6 - Populating 4 types of messages in the message queue
  • Line 8 - Receive message type 3. Successful
  • Line 15 - Receive message type 3.  No message present
  • Line 19 - Receive message type 2. Successful
  • Line 26 - Receive message type 4. Successful
Lets clear the queue using 'ipcrm -a' and proceed to next type

Zero: Reads the first receive message in the whole message queue, irrespective of the type

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@msgq]# ./write2
Key - 41014da0 ;MessageId - 360448
Sent Type: 1 Data: its my world 1
Sent Type: 2 Data: its my world 2
Sent Type: 3 Data: its my world 3
Sent Type: 4 Data: its my world 4

[root@msgq]# ./read2 0
Key - 41014da0 ;MessageId - 360448
Received Data,its my world 1
Received Data type, 1

Received Data,its my world 2
Received Data type, 2

Received Data,its my world 3
Received Data type, 3

Received Data,its my world 4
Received Data type, 4

No messages
  • Line 1-6 - Populating messages of different type
  • Line 8 - Passing the value of type 0
  • Line 10-20 - Receiving the messages 1, 2, 3, 4 in the same order as in lines 1-6
Negative: Receives all the messages belonging to the types less than the absolute value of the number passed in fifo order

 
 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
[root@msgq]# ./write2
Key - 41014da0 ;MessageId - 360448
Sent Type: 1 Data: its my world 1
Sent Type: 2 Data: its my world 2
Sent Type: 3 Data: its my world 3
Sent Type: 4 Data: its my world 4

[root@msgq]# ./read2 -2
Key - 41014da0 ;MessageId - 360448
Received Data,its my world 1
Received Data type, 1

Received Data,its my world 2
Received Data type, 2

No messages

[root@msgq]# ipcrm -a

[root@msgq]# ./write2
Key - 41014da0 ;MessageId - 393216
Sent Type: 1 Data: its my world 1
Sent Type: 2 Data: its my world 2
Sent Type: 3 Data: its my world 3
Sent Type: 4 Data: its my world 4

[root@msgq]# ./read2 -3
Key - 41014da0 ;MessageId - 393216
Received Data,its my world 1
Received Data type, 1

Received Data,its my world 2
Received Data type, 2

Received Data,its my world 3
Received Data type, 3

No messages
  • Line 1-6 - Populating messages of different types
  • Line 8 - Receiving the type '-2', meaning retrieve all messages less than type 2 in FIFO order
  • Line 18 - Clearing the message queue
  • Line 20-25 - Populating messages of different types
  • Line 27 - Receiving the type '-3', meaning retrieve all messages less than type 3 in  FIFO order

No comments:

Post a Comment