2014-03-04 45 views
0

我正在嘗試在C中使用消息隊列實現一個IPC機制來進行電話對話。我創建了兩個.c文件,一個用於調用者,另一個用於接收者。在每個.c文件中,我創建了兩個線程,一個用於發送消息,另一個用於接收消息。每個線程創建它的消息隊列。來自調用者的發送消息線程和來自接收者的接收消息線程共享相同的隊列,而另一個則相同。在C中使用消息隊列的IPC機制

正在創建消息隊列,但每當我輸入要發送的消息時,都會失敗。 msgsnd( - , - , - , - )總是返回-1。

的caller.c文件如下:

#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; 
} 

的receiver.c文件如下(這類似於caller.c文件):

#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; 
} 

我需要的呼叫者和發送者都可以按照他們的意願接收和發送消息。

+0

失敗如何?具體的錯誤是什麼?並且您沒有告訴我們您正在處理的操作系統,而是添加了'operating-system'標籤。刪除該標籤並告訴我們。 –

+0

我正在UNIX操作系統上運行它。它每次顯示「消息發送失敗」。 msgsnd( - , - , - , - )總是返回-1。 – user2504710

+0

好的,在失敗時設置了'errno'是什麼意思?調試是一個有條不紊的過程,你需要閱讀手冊頁。 –

回答

1

您收到的errno表示您將無效參數傳遞給msgsnd。根據man page for msgsnd

[EINVAL] 將對msqid的值不是有效的消息隊列標識符,或MTYPE的值小於1;或者msgsz的值小於0或大於系統強加的限制。 Blockquote

我的猜測是msqid是違規參數。檢查調試器中的值或將其打印出來。

編輯:麥克威爾金斯發現它。他的評論:

mtype可能是問題(而不是msqid)。 mtype需要大於0. OP中的代碼 專門將其設置爲0

+1

我認爲你引用的文字顯示了答案。 mtype可能是問題(而不是msqid)。 mtype需要大於0. OP中的代碼特別將其設置爲0. –

+0

謝謝Carey和Mark,它解決了問題。 – user2504710

+0

@MarkWilkins好的。添加到答案中。 –