Problem with message queues / msgrcv - Unix

This is a discussion on Problem with message queues / msgrcv - Unix ; Hi netties, posted this in a different group already, which seems to be inappropriate. I create a message queue with msgget(), sent a 5-byte message to it with msgsnd() and try to receive the queue's content with msgrcv(). Everything seems ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Problem with message queues / msgrcv

  1. Problem with message queues / msgrcv

    Hi netties,

    posted this in a different group already, which seems to be
    inappropriate.


    I create a message queue with msgget(), sent a 5-byte message to it
    with msgsnd() and try to receive the queue's content with msgrcv().
    Everything seems to work fine, apart from the fact that I get back
    only the last byte back from the original message (after sending the
    message ipcs -qA shows clearly that there are 5 Bytes waiting in the
    queue).


    I am running Solaris 10 8/07 with gcc 3.4.3 as the compiler.


    As being not such an experienced C-programmer it could be possible
    hat
    I am something doing wrong when fiddling around with structures,
    pointers etc., but I cannot find it.


    The source code (see below) was compiled in the following way:


    gcc -fpic msgqueue_tst.c -o mgsqueue_tst


    The output is:


    Hi there, here is msgget!
    msqid: 16777338
    msgget: msgget succeeded (msqid: 16777338)
    Hi there, here is msgsnd!
    msgsnd: message was successfully placed into message queue 16777338.
    Hi there, here is msgrcv!
    msgflg: 3600
    msgtyp: 0
    msgrcv: message was successfully read from message queue 16777338.
    We finally made it past the invocation ( msgactsz = 1, mtext: o )!


    The source:


    #include
    #include
    #include
    #include


    int main() {


    printf("Hi there, here is msgget!\n") ;


    /* Parameters */
    key_t key = 0 ;
    int msgflg = 03600 ;


    /* Return value */
    int msqid ;


    /* Create the message queue */
    msqid = msgget( key, msgflg ) ;
    printf( "msqid: %i\n", msqid) ;
    if ( msqid == -1 )
    {


    printf("msgget: initializing message queue failed!\n") ;
    perror("errno:") ;
    return -1 ;


    } else
    {


    printf("msgget: msgget succeeded (msqid: %i)\n", msqid) ;


    }


    printf("Hi there, here is msgsnd!\n") ;


    /* Parameters */
    size_t msgsz = 5 ;


    struct message {


    long mtype ;
    const char *mpointer ;


    } ;


    struct message msg ;


    msg.mtype = 0 ;
    msg.mpointer = "hello" ;


    if ( msgsnd( msqid, msg.mpointer, msgsz, msgflg ) == 0 ) {


    printf("msgsnd: message was successfully placed into message
    queue %i.\n", msqid) ;


    } else
    {


    printf("msgsnd: sending message to message queue %i failed.
    \n", msqid) ;
    return -1 ;


    }


    printf("Hi there, here is msgrcv!\n") ;


    /* Parameters */
    int msgtyp = 0 ;


    struct message_rcv {


    long mtype ;
    char messtxt[msgsz] ;


    } *msg_rcv ;


    msg_rcv = malloc( msgsz*sizeof(char) + sizeof(long) ) ;


    /* Receive the message */


    printf("msgflg: %5o\n", msgflg) ;
    printf("msgtyp: %d\n", msgtyp) ;


    long msgactsz ; // Actual number of bytes placed in the structure


    if ( msgactsz = msgrcv( msqid, msg_rcv, msgsz, msgtyp,
    IPC_NOWAIT ) != -1 ) {


    printf("msgrcv: message was successfully read from message
    queue
    %i.\n", msqid) ;


    } else
    {


    printf("msgrcv: receiving message from message queue %i
    failed.
    \n", msqid) ;
    fprintf( stderr, "errno: %i\n", errno ) ;


    return -1 ;


    }


    printf("We finally made it past the invocation ( msgactsz = %d,
    mtext: %s )!\n", msgactsz, msg_rcv->messtxt ) ;


    return 0 ;



    }


    Hope somebody can help!

    Cheers


    Bernd



  2. Re: Problem with message queues / msgrcv

    On Tue, 27 May 2008 05:09:38 -0700, bernd wrote:
    > if ( msgactsz = msgrcv( msqid, msg_rcv, msgsz, msgtyp,
    > IPC_NOWAIT ) != -1 ) {


    Better add parens around msgactsz assignment:
    if ((msgactsz = msgrcv(...)) != -1)

    --
    Thomas


  3. Re: Problem with message queues / msgrcv

    On May 27, 8:09*am, bernd wrote:
    > * * /* Parameters */
    > * * size_t msgsz = 5 ;
    >
    > * * struct message {
    >
    > * * * long mtype ;
    > * * * const char *mpointer ;
    >
    > * * } ;
    >
    > * * struct message msg ;
    >
    > * * msg.mtype = 0 ;
    > * * msg.mpointer = "hello" ;
    >
    > * * if ( msgsnd( msqid, msg.mpointer, msgsz, msgflg ) == 0 ) {


    Don't you need something like the following when sending?

    struct message {
    long mtype ;
    char mdata[32] ;
    } ;

    struct message msg ;
    msg.mtype = 0 ;
    strcpy(msg.mdata, "hello") ;

    if (msgsnd(msqid, &msg, strlen(msg.mdata), msgflg ) == 0 ) {

  4. Re: Problem with message queues / msgrcv

    > Don't you need something like the following when sending?
    >
    > struct message {
    > long mtype ;
    > char mdata[32] ;
    >
    > } ;


    Indeed, yes he does.

    susv3 defines messages being a struct like:
    struct message {
    long mtype ;
    char mdata[1] ;
    } ;

    The mdata field is used to store your actual message and hence even
    defined as data[1] you should define your one with whatever size you
    want:
    struct message {
    long mtype ;
    char mdata[??] ;
    } ;

    Why such thing ?
    So you can create messages like:
    struct mymsg {
    long mtype;
    char mdata[128];
    int flag_01;
    char custom_ticker[4];
    ...
    };
    and still pass them to msgsnd using this "hack" i.e. cast the pointer
    you provided into a pointer to a sysv struct msg.
    The point being that if you design you data structures to be used by
    the sysv messages queues, you can avoid copying from your data to sysv
    messages and rely only on casting from one to another.

    -- paulo

+ Reply to Thread