I am trying to implement a IPC mechanism for telephone conversation using message queues in C. I have created two .c files, one for caller and one for receiver. In each .c file i have created two threads , one for sending messages and another for receiving messages. Each thread creates its message queue. The send message thread from caller and the receive message thread from receiver share the same queue and same for the other.

The message queues are being created but whenever i enter some message to be sent , it fails. The msgsnd(-,-,-,-) always returns -1.

The caller.c file is as follows :

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

struct msgbuf
{
  long mtype;
  char mtext[50];
}SEND_BUFFER,RECEIVE_BUFFER;

int send_msgQ_id, receive_msgQ_id;
key_t send_key,receive_key;

void * send_message(void * a)
{
send_key = ftok("Caller.c", 'B');
if(send_key==-1)
{
    printf("\n caller send key error");
    exit(1);
}
send_msgQ_id = msgget(send_key, 0666 | IPC_CREAT);
if(send_msgQ_id==-1)
{
    printf("\n caller send msgget error");
    exit(1);
}

printf("\n Enter lines of text, ^D to quit:\n");

    while(fgets(SEND_BUFFER.mtext, sizeof(SEND_BUFFER.mtext), stdin) != NULL)
    {
        SEND_BUFFER.mtype = 0;

        int len = strlen(SEND_BUFFER.mtext);
        if (SEND_BUFFER.mtext[len-1] == '\n')
            SEND_BUFFER.mtext[len-1] = '\0';
        printf("\n Attemping to send %s\n", SEND_BUFFER.mtext);
        if(msgsnd(send_msgQ_id, &SEND_BUFFER, len+1, 0)==-1)
            printf("\n msg sendign error\n");
    }
int i =0;
while(i<9999)
    i++;
msgctl(send_msgQ_id, IPC_RMID, NULL);
return;
}

void * receive_message(void * a)
{
receive_key = ftok("Receiver.c", 'B');
if(receive_key==-1)
{
    printf("\n caller receive key error");
    exit(1);
}
receive_msgQ_id = msgget(receive_key, 0777 | IPC_CREAT);
 if(receive_msgQ_id==-1)
 {
     printf("\n caller receive msgget error");
     exit(1);
 }

printf("\n Ready to receive ");
while(1)
{
   if( msgrcv(receive_msgQ_id, &RECEIVE_BUFFER, sizeof(RECEIVE_BUFFER.mtext), 0, 0)!=-1)
    printf("Received : %s\n", RECEIVE_BUFFER.mtext);
}
return;
}

void initialize()
{

pthread_t send_thread,receive_thread;
pthread_create(&send_thread,NULL,send_message,NULL);
pthread_create(&receive_thread,NULL,receive_message,NULL);
pthread_join(send_thread,NULL);
pthread_join(receive_thread,NULL);
return;
}

int main()
{
printf("\n\n *** Caller Program ***\n");
initialize();
return 0;
}

The receiver.c file is as follows (it is similar to the caller.c file) :

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

struct msgbuf
{
long mtype;
char mtext[50];
}SEND_BUFFER,RECEIVE_BUFFER;

int send_msgQ_id, receive_msgQ_id;
key_t send_key,receive_key;

void * send_message(void * a)
{
send_key = ftok("Receiver.c", 'B');
if(send_key==-1)
{
    printf("\n receiver send key error");
    exit(1);
}
send_msgQ_id = msgget(send_key, 0777);
if(send_msgQ_id==-1)
{
    printf("\n receiver msgget error ");
    exit(1);
}
printf("\n Enter lines of text, ^D to quit:\n");

    SEND_BUFFER.mtype = 0;
    while(fgets(SEND_BUFFER.mtext, sizeof(SEND_BUFFER.mtext), stdin) != NULL)
    {
        int len = strlen(SEND_BUFFER.mtext);
        if (SEND_BUFFER.mtext[len-1] == '\n')
            SEND_BUFFER.mtext[len-1] = '\0';
        msgsnd(send_msgQ_id, &SEND_BUFFER, len+1, 0);
    }
    int i =0;
    while(i<9999)
        i++;
msgctl(send_msgQ_id, IPC_RMID, NULL);
return;
}

void * receive_message(void * a)
{
receive_key = ftok("Caller.c", 'B');
if(receive_key==-1)
{
    printf("\n receiver receiver key error");
    exit(1);
}
receive_msgQ_id = msgget(receive_key, 0666);
if(receive_msgQ_id==-1)
{
    printf("\n msgget error");
    exit(1);
}

while(1)
{
    if(msgrcv(receive_msgQ_id, &RECEIVE_BUFFER, sizeof(RECEIVE_BUFFER.mtext), 0, 0)==-1)
        printf("\n msg receiving error");
    else
        printf("Received : %s\n", RECEIVE_BUFFER.mtext);
}
return;
}

void initialize()
{
pthread_t send_thread,receive_thread;
pthread_create(&receive_thread,NULL,receive_message,NULL);
pthread_create(&send_thread,NULL,send_message,NULL);
pthread_join(send_thread,NULL);
pthread_join(receive_thread,NULL);
return;
}

int main()
{
printf("\n\n *** Receiver Program ***\n");
initialize();
return 0;
}

I need that both the caller and sender can receive and send messages at their free will.

有帮助吗?

解决方案

The errno you're getting indicates you're passing an invalid argument to msgsnd. According to the man page for msgsnd:

[EINVAL] The value of msqid is not a valid message queue identifier, or the value of mtype is less than 1; or the value of msgsz is less than 0 or greater than the system-imposed limit. Blockquote

My guess would be that msqid is the offending parameter. Either check the value in a debugger or print it out.

EDIT: Mike Wilkins spotted it. His comment:

mtype is likely the issue (not msqid). mtype needs to be > 0. The code in the OP specifically sets it to 0

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top