Message Queue Problem

Hi all,

I need help about message queues, i have a server-client program that communicates each other via msg queue, firstly server opens its msg queue and waits for msg then client opens server msg queue and its own msg queue(for receiving msg from server,clients sends msg to server msg queue,but receives their reply from their private msg queue).
I have problem at sending generated structure to the server :(...

I am also sending my source code for help..

//Here is my client source
#define MAXLEN 32	
#define MSGKEY	5L

typedef struct my1_msgbuf
{
        int receiver_id;  //server msg queue
	int sender_id;  //client msg queue
        char message[MAXLEN]; //msg to server
}my_msgbuf;

void main (int argc, char *argv[])
{
        my_msgbuf 	buffer;
        int		msgID;
	int myId;


        if (argc<2)
        {
                printf("Give message as parameter!");
                exit(-1);
        }

        //create and get a message queue
        if ((msgID=msgget(MSGKEY,0666|IPC_CREAT))<0)
        {
                perror("Error getting msg queue.");
                exit(-1);
        }

	if((myId=msgget(112233,0666|IPC_CREAT))<0){//create client msgq-im just testing with 112233
		perror("Error getting client msg queue!\n");
		exit(-2);
	}

        //copy the message into the buffer (prepare)
        strcpy(buffer.message,argv[1]);
        buffer.receiver_id=msgID; //server msgq id
	buffer.sender_id=myId;//client msg q id - server need to know client id

        //send the message to the OS-managed buffer
        if (msgsnd(msgID,&buffer,sizeof(buffer.message),0)<0)//here i have an invalid argument exception!!!
        {
                perror("Error writing to message queue.");
                exit(-1);
        }

        printf("Message has been send.\n\n");
	//wait msg from server
	if(msgrcv(myId,&buffer,sizeof(buffer),0L,0)<0){//waiting server to reply me..
		printf("Unable to receive client msg\n.");
		exit(1);
	}

        exit(0);
}

//Here is the server side
define MAXLEN	256
#define MSGKEY	5L

typedef struct my1_msgbuf
{
	int receiver_id;
        int sender_id;
        char message[MAXLEN];
}my_msgbuf;

void main ()
{
        my_msgbuf 	buffer;
        int		msgID;
	int temp;

        //create and get a message queue
        if ((msgID=msgget(MSGKEY,0666|IPC_CREAT))<0)
        {
                perror("Error getting msg queue.");
                exit(-1);
        }

        //RECEIVE MESSAGE FROM OPERATING SYSTEMS QUEUE

        if (msgrcv(msgID,&buffer,
        sizeof(buffer.message),0L,0)<0)
        {
                perror("Error receiving message from Queue.");
                exit(-1);
        }

        printf("\nMessage read from queue:\n\n");
        printf("MESSAGE: %s\n",buffer.message);
	printf("Sender id: %d\n",buffer.sender_id);
	printf("Receiver id: %d\n",buffer.receiver_id);

	temp = buffer.receiver_id;
	buffer.receiver_id = buffer.sender_id;
	buffer.sender_id = temp;

	//Send same msg to the client that send..
while(msgsnd(buffer.receiver_id,&buffer,sizeof(buffer),0)>0);

        //DELETE QUEUE

        if (msgctl(msgID,IPC_RMID,0)<0)
        {
                perror("Error deleting message queue.");
                exit(-1);
        }

        exit(0);
}

What is the problem here?
Thanks.

typedef struct my1_msgbuf
{
        int receiver_id;  //server msg queue
	int sender_id;  //client msg queue
        char message[MAXLEN]; //msg to server
}my_msgbuf;

No OS that I have ever seen has a msgbuf that looks like that. Read the man page for msgsnd:

struct  mymsg {
        long  mtype;     /* message type */
        char  mtext[1];  /* message text */
}

Hey SaTYR, I have to do a program which is very similar to yours, and I was wondering if you got yours going.

Bye!

Hi there, i wrote the code but i forgot to update my message..
Now i'm uploading my code...
While you are compiling, make

client.txt->client.c
server.txt->server.c
local.txt->local.h

probably you need to compile server.c like
gcc -o server server.c -lpthread
for including thread objects.

This is the default structural approach of message queues Perderabo

struct  mymsg {
        long  mtype;     /* message type */
        char  mtext[1];  /* message text */
}

but the main idea is the first long type describes the type of the message and the char pointer shows the starting address of other things in the structure...

if you send a custom structure and receive it with the same structure, you got the message. (Mainly the flexibility of the message queue comes here, you can send and receive your custom structure.)

typedef struct message{
	long mtype;
	int receiver_id;
	int sender_id;
	char type;
	int length;
	
	char data[MAXDATA];
}msg_tb;

Here, under the 'long mtype' understood with a char pointer by the message queue, because at the message queue process it only need the starting address of the message (size of the message gave at the msgsnd command) so that you can send whatever structure you want with the message queue.

Thats it. :slight_smile:

That is fine hope it will help me also

hi me to have a problem with msg queues.
let it be 3 processes a,b,and c.'a' is sending msg to 'c' and 'c' is sending it back to 'b'.i had used 2 msg queues here.one for 'a' and 'c' and the other for 'c' and 'b'.When something happens to 'c',how does process 'a' and 'b' knows that 'c' got some problem?????

You can do it with signals.When the problem was appeared, send a signal and let your processes to catch it.

I think its too late even though i am forwarding to u . check it out
server.c

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

#define MSGSZ     128

#define mess    122


 typedef struct msgbuf {
          long    mtype;
          char    mtext[MSGSZ];
          } message_buf;

//for reciving structure
typedef struct msg1 {
         long    type;
         char    message[mess];
         } mess_buf;

main()
{
    int msqid;
    int msgflg = IPC_CREAT | 0666;
    key_t key;
    size_t buf_length;
    message_buf sbuf;
    key = 1234;

// for reciving the data

    int msgid;
    int msgflag = IPC_CREAT | 0666;
    key_t lock;
    mess_buf gbuf;
//     size_t buffer_length;

    lock = 123;
    

(void) fprintf(stderr, "\nmsgget: Calling msgget(%#lx,%#o)\n",key, msgflg);

    if ((msqid = msgget(key, msgflg )) < 0) {
        perror("msgget");
        exit(1);
    }
    else 
     (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);

     // We'll send message type 1


    sbuf.mtype = 1;

    (void) strcpy(sbuf.mtext, "Did you get this?");

    buf_length = strlen(sbuf.mtext) + 1 ;

     //Send a message.
     
    if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) {
       printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
        perror("msgsnd");
        exit(1);
    }

   else 
      printf("Message: \"%s\" Sent\n", sbuf.mtext);
      
//     exit(0);

//this is to recive the message


(void) fprintf(stderr, "\nmsgget: Calling msgget(%#lx,%#o)\n",lock, msgflag);

    if ((msgid = msgget(lock, msgflag )) < 0) {
        perror("msgget");
        exit(1);
    }
    else 
     (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msgid);


    
    
      //recive the message form the sender

    if (msgrcv(msgid, &gbuf,mess, 1, 0) < 0) {
        perror("msgrcv");
        exit(1);
    }

    
     // Print the answer.
     
    printf("recived:%s\n", gbuf.message);
    exit(0);


}

client.c

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

#define MSGSZ     128

#define mess    122

typedef struct msgbuf {
    long    mtype;
    char    mtext[MSGSZ];
} message_buf;

// for sending structure

typedef struct msg1 {
         long    type;
         char message[mess];
         } mess_buf;


main()
{
    int msqid;
    key_t key;
    int msgflg = IPC_CREAT | 0666;
    message_buf  rbuf;
    key = 1234;

// for the tranmission

 int msgid;
    int msgflag = IPC_CREAT | 0666;
    key_t lock;
    mess_buf tbuf;
    size_t buf_length;
    lock = 123;

// reciving starts here

    if ((msqid = msgget(key, 0666)) < 0) {
        perror("msgget");
        exit(1);
    }

     // Receive an answer of message type 1.
     
    if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0) {
        perror("msgrcv");
        exit(1);
    }
 
    printf("%s\n", rbuf.mtext);
//     exit(0);


// now we r sending the message to the server



(void) fprintf(stderr, "\nmsgget: Calling msgget(%#lx,\%#o)\n",lock, msgflag);

    if ((msgid = msgget(lock, msgflag )) < 0) {
        perror("msgget");
        exit(1);
    }
    else 
     (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msgid);


    tbuf.type = 1;
 
    (void) strcpy(tbuf.message, "r u hearing me?");
     buf_length = strlen(tbuf.message) + 1 ;
     // Send a message.
     
    if (msgsnd(msgid, &tbuf, buf_length, IPC_NOWAIT) < 0) {
        printf ("%d, %d, %s, %d\n", msgid, tbuf.type, tbuf.message, buf_length);
        perror("msgsnd");
        exit(1);
    }

   else 
      printf("Message: \"%s\" Sent\n", tbuf.message);

    exit(0);

}