2014-03-26 90 views
0

我在C linux中實現消息隊列。我發送integer = 17並收到integer = 0。請看下面,讓我知道我的msgsndmsgrcv功能有什麼問題。 請注意這一點:將rbuf存儲在rbuf->m->msglenrbuf->mtype中。IPC在C中使用消息隊列:在接收時出錯

在發送過程

msgsnd(msqid, sbuf,sizeof(int), 0); 
printf("\nmsglen = %d",rbuf->m->msglen); // 17 

在接收過程。兩者都有相同的msqid。我已驗證它。

msgrcv(msqid, rbuf, sizeof(int), 1, 0); 
printf("\nmsglen = %d",rbuf->m->msglen); // 0 

//msqid=98305, some valid id 

這裏是我在另一個文件中定義的結構體定義。

typedef struct message1 
{ 
    int msglen; 
    unsigned char *cp; 
}msg1; 

typedef struct msgbuf 
{ 
    long mtype; 
    msg1 *m; 
} message_buf; 
+0

'msgrcv()'調用後的'errno'值是什麼? – bosnjak

+0

沒有。收到的字節數 – user3436838

+0

對不起,我用適當的問題更新了我的評論。什麼是errno值? – bosnjak

回答

1

您發送包含一個指向您的MESSAGE1結構的消息。接收過程將該指針取消引用,但在該過程中它不指向相同的事物。事實上,我很驚訝你沒有得到一個段錯誤。

你應該定義msgbuf這樣的:

typedef struct msgbuf 
{ 
    long mtype; 
    msg1 m; 
} message_buf; 

從而使MSG1結構包含,而不是它指向的msgbuf內。

此外,您需要指定的大小是sizeof(message_buf),而不是sizeof(int)。

+0

這兩個進程都在同一臺機器上。我是一名學生,所以只是在嘗試。 我做了sizeof(int),因爲我想先收到消息的長度,這樣我就可以在接收過程中爲cp分配空間,然後接收cp。 – user3436838

+0

@ user3436838它們在同一臺機器上並不重要。不同的進程不能訪問其他內存。 – harmic

+0

謝謝先生。它正在工作。但問題是:我首先想發送msglen,發送成功,然後我想發送cp。我已經爲cp分配了空間** rbuf-> m.cp = malloc(rbuf-> m.msglen); ** 然後** msgrcv(msqid,rbuf,rbuf-> m.msglen,1,0) **這是給段故障。任何關於它的想法。 – user3436838

0
//header files 
#include"msgbuf.h" //where I have put my structures 
#define AUTOMATIC 1 
#define USER_DATA 2 

int main() 
{ 
    int msgflg = IPC_CREAT | 0666,ch,len=0; 
    size_t msgsize = 0; 
    int msqid; 
    key_t key; 
    message_buf *sbuf; 
    char ans; 
    char *data; 
    key = ftok("/home/user",15); 

    printf("Do you want to send messages\t"); 
    scanf("%c",&ans); 
    getchar(); 
    if (((ans=='y' || ans=='Y') && (msqid = msgget(key, msgflg)) ==-1)) 
    {  perror("msgget"); 
      exit(1); 
    } 
    else 
    fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid); 

    while(ans=='y' || ans=='Y') 
    { 
      printf("\n1. Automatic data\n2. Enter data\n3. Exit\nEnter your choice\t"); 
      scanf("%d",&ch); 
      getchar(); 
      switch(ch) 
      { 
        case AUTOMATIC: len=strlen("Did you get this?"); 

            sbuf=malloc(len+sizeof(int)); 
            memset(sbuf, 0, sizeof(message_buf)); 
            sbuf->m=malloc(len+sizeof(int)); 
            memset(sbuf->m, 0, sizeof(msg1)); 

            sbuf->m->msglen=len; 
            sbuf->m->cp=malloc(sizeof(len)); 
            strncpy(sbuf->m->cp, "Did you get this?",strlen("Did you get this?")); 
            sbuf->m->cp[strlen(sbuf->m->cp)]='\0'; 
            break; 
        case USER_DATA: printf("\nEnter data\t"); 
            fflush(stdout); 
            len = getline(&data, &msgsize, stdin); 

            sbuf=malloc(len+sizeof(int)); 
            memset(sbuf, 0, sizeof(message_buf)); 
            sbuf->m=malloc(len+sizeof(int)); 
            memset(sbuf->m, 0, sizeof(msg1)); 

            strcpy(sbuf->m->cp, data); 
            sbuf->m->cp[strlen(sbuf->m->cp)]='\0'; 
            sbuf->m->msglen=len; 
            break; 
        case 3: msgctl(msqid, IPC_RMID, NULL); 
          printf("\nQueue with q id = %d is removed\n",msqid); 
          exit(1); 
        default:printf("\nTRY AGAIN\t"); 
          scanf("%c",&ans); 
          getchar(); 
      } 
      printf("\nmsglen = %d\nmsgcp= %s",sbuf->m->msglen,sbuf->m->cp); 
      /* Send a message */ 
      sbuf->mtype=1; 
      if (msgsnd(msqid, sbuf,2*sizeof(int), 0) < 0) 
      { 
     printf("Msg q id= %d\nMsg type= %d\nMsg Text %s\nMsg Len= %d\n", msqid, sbuf->mtype, sbuf->m->cp,sbuf->m->msglen); 
        perror("msgsnd"); 
        exit(1); 
      } 
      else 
      printf("\nMessage: %s\n Sent\n", sbuf->m->cp); 
    } 
    msgctl(msqid, IPC_RMID, NULL); 
    printf("\nQueue with q id = %d is removed\n",msqid); 
    return 0; 
} 

現在接收代碼

//header files 
#include"msgbuf.h" 
int main() 
{ 
    int msqid; 
    key_t key; 
    int msgflg = 0666; 
    message_buf *rbuf; 
    int msg_len_rcvd=0; 

    rbuf=malloc(150); 
    rbuf->m=malloc(100); 
    key = ftok("/home/user",15); 
    if ((msqid = msgget(key, msgflg)) ==-1) 
    { 
      perror("msgget"); 
      exit(1); 
    } 
    printf("\n\n%d\n",msqid); 
    /* Receive an answer of message type 1. */ 
    while(1) 
    { 
      if ((msg_len_rcvd=msgrcv(msqid, rbuf, 2*sizeof(int), 1, 0)) < 0) 
      { 
        perror("msgrcv"); 
        exit(1); 
      } 
      else 
      { 
        printf("\n Number of bytes received:: %d", msg_len_rcvd); 
        printf("\nmtype1 = %d",rbuf->mtype); 
        printf("\nmsglen= %d",rbuf->m->msglen); 
      } 
      break; 
    } 
    return 0; 
}