Here I have to send and receive dynamic data using a SysV message queue.
so in structure filed i have dynamic memory allocation char * because its size may be varies.
so how can i receive this type of message at receiver side.
Please let me know how can i send dynamic length of data with message queue.
I am getting problem in this i posted my code below.
send.c
/*filename : send.c
*To compile : gcc send.c -o send
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct my_msgbuf {
long mtype;
char *mtext;
};
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
static int count = 0;
char temp[5];
int run = 1;
if ((key = ftok("send.c", 'B')) == -1) {
perror("ftok");
exit(1);
}
printf("send.c Key is = %d\n",key);
if ((msqid = msgget(key, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
printf("Enter lines of text, ^D to quit:\n");
buf.mtype = 1; /* we don't really care in this case */
int ret = -1;
while(run) {
count++;
buf.mtext = malloc(50);
strcpy(buf.mtext,"Hi hello test message here");
snprintf(temp, sizeof (temp), "%d",count);
strcat(buf.mtext,temp);
int len = strlen(buf.mtext);
/* ditch newline at end, if it exists */
if (buf.mtext[len-1] == '\n') buf.mtext[len-1] = '\0';
if (msgsnd(msqid, &buf, len+1, IPC_NOWAIT) == -1) /* +1 for '\0' */
perror("msgsnd");
if(count == 100)
run = 0;
usleep(1000000);
}
if (msgctl(msqid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(1);
}
return 0;
}
receive.c
/* filename : receive.c
* To compile : gcc receive.c -o receive
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct my_msgbuf {
long mtype;
char *mtext;
};
int main(void)
{
struct my_msgbuf buf;
int msqid;
key_t key;
if ((key = ftok("send.c", 'B')) == -1) { /* same key as send.c */
perror("ftok");
exit(1);
}
if ((msqid = msgget(key, 0644)) == -1) { /* connect to the queue */
perror("msgget");
exit(1);
}
printf("test: ready to receive messages, captain.\n");
for(;;) { /* receive never quits! */
buf.mtext = malloc(50);
if (msgrcv(msqid, &buf, 50, 0, 0) == -1) {
perror("msgrcv");
exit(1);
}
printf("test: \"%s\"\n", buf.mtext);
}
return 0;
}
A couple of ways to solve your problem are:
'\0'.Edit: How to use
msgsndandmsgrcv:Your usage of the structure and
msgsndis wrong, as the function expects the whole message to be one continuous memory area. Examples such as this use a structure with normal fields in it, or like this (at the bottom) which uses a fixed length string array.You can send dynamic data having the structure size being dynamic as well. The trick here is to use a small fixed-size structure, and allocate more data than is needed.
Lets rewrite parts of your example sender code:
The above code handles sending of dynamic strings, as long as the are less than 63 characters (the size of the temporary string minus one).
Unfortunately
msgrcvdoesn’t really support receiving of dynamically sized data. This can be helped by not using theMSG_NOERRORflag, and check for errorE2BIGand then usingreallocto get a bigger message buffer.Something like this for receiving:
The above code for receiving only receives one single message. If you want it to match the sender which sends lots of messages, then put the receiving code in a function, and call it in a loop.
DISCLAIMER: This code is written directly in the browser, only reading the manual pages. I have not tested it.