2013-10-03 92 views
2

我已經完成了一個簡單的分叉程序,其中一個進程通過使用mq_send和mq_receive向其父進程發送一個字符數組,並輸出反向字符串。但是,由於某些原因,當我有時輸入要發送的字符串時,程序的接收端添加了字符。更重要的是,這似乎是隨機的,因爲再次發送相同的字符串將提供正確的輸出。當發送消息隊列POSIX時接收額外的字符

這裏是整個代碼,以及之後的輸出示例。

#include <stdio.h> /* printf */ 
#include <sys/types.h> /* pid_t */ 
#include <unistd.h> /* get_pid */ 
#include <stdlib.h>  /* exit, EXIT_FAILURE */ 
#include <sys/wait.h> /* wait */ 
#include <mqueue.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <string.h> 

#define MAX_STR_LEN 500 

void reverse(char s[]); 
void clientFunction(const char *msgqname); 
void serverFunction(const char *msgqname); 
int main(void) 
{ 
    //A 
    char msgQName[] = "/queue"; 
    //B 
    pid_t pid; 
    pid = fork(); 
    if (pid == 0){  
     clientFunction(msgQName); 
    } 
    else { 
     usleep(10L); 
     serverFunction(msgQName); 
    } 
    return(0); 

} 
void clientFunction(const char *msgqname){ 
    //C 

    mqd_t mqident = mq_open(msgqname, O_WRONLY|O_CREAT , 0666, NULL); 
    //D 
    if (mqident == -1){ 
     printf("Error opening message queue. Exiting program. \n"); 
     exit(0); 
    } 
    char str[MAX_STR_LEN]; //Keep the string that has been read from input and written on the pipe 
    memset(str,0,strlen(str)); 
    while(1){ 

     printf("Enter an string:"); 
     gets(str); //Reads the string from input 
     printf("%i\n",strlen(str)); 
     unsigned len = (unsigned) strlen(str); //Finds the length of the string 
     int sent = mq_send(mqident,str,len,0); 
     if (sent == -1){ 
      printf("Error sending message. Exiting program. \n"); 
      exit (0); 
     } 
     usleep(10L); 
     memset(str,0,strlen(str)); 
    } 

} 
void serverFunction(const char *msgqname){ 
    //F 
    mqd_t mqident = mq_open (msgqname,O_RDONLY|O_CREAT , 0666, NULL); 

    if (mqident == -1){ 
     printf("Error opening message queue. Exiting program. \n"); 
     printf("Error : %s\n", strerror(errno)); 
     exit(0); 
    } 
    char str1[MAX_STR_LEN]; 
    memset(str1,0,strlen(str1)); 
    struct mq_attr attr; 
    while(1){ 
     //G 
     mq_getattr(mqident,&attr); 
     //H 
     ssize_t receive = mq_receive(mqident,str1,attr.mq_msgsize,0); 
     if (receive == -1){ 
      printf("Error receiving message. Exiting program. \n"); 
      exit(0); 
     } 
     printf("%i, %i\n",strlen(str1), attr.mq_msgsize); 
     reverse(str1); 
     printf("What you wrote in reverse was:%s\n", str1); 
     memset(str1,0,strlen(str1)); 
    } 

} 
void reverse(char s[]) 
{ 
     int length = strlen(s) ; 
     int c, i, j; 

     for (i = 0, j = length - 1; i < j; i++, j--) 
    { 
    c = s[i]; 
    s[i] = s[j]; 
    s[j] = c; 
     } 
} 

實施例的輸出,當與在終端

Enter an string:tester 1234567890  
17 
21 
What you wrote in reverse was:1��0987654321 retset 
Enter an string:tester 1234567890 
17 
17 
What you wrote in reverse was:0987654321 retset 
Enter an string: 

在輸出中的兩個整數值-o和-lrt GCC編譯是什麼我用於檢查的長度,所述第一個是發送字符串的strlen,第二個字符串是接收字符串的strlen。

我確保在初始化和printf後立即清空字符串,所以我不知道這些神祕人物來自哪裏。

回答

1

空隙serverfunction()空隙clientFunction()

替換memset(str1,0,strlen(str1))

memset(str1,0,sizeof(str1))

sizeof將給予總數組

現在大概你不會收到垃圾數據的sizeof。

+0

剛剛嘗試過,並沒有改變一件事。 – user2844080

+0

@ user2844080我身邊上面的修正工作正常。您使用的操作系統和編譯器 – sujin

+0

@ user2844080用'sizeof'替換所有的memset。 – sujin

1

正如你所看到的,第一次看起來比收到的字符多了四個字符。 原因是字符串str1不是NULL終止,因爲 memset初始化字符數組str1。 嘗試將其更改爲:

memset(str1, 0, MAX_STR_LEN); 

和你的程序應該正常工作。


關於第二個想法,你不應該需要memset可言,如果你正確地發送您的字符串。您的gets將在str的末尾附加。但len(str)將不會計算在內。這意味着你只需發送真實的字符,而不是最終的'\0'

有兩種更好的方法來解決您的問題,因此:

  1. 對方追加最終'\0',在接收到的字符串。您可以通過添加該行來執行此操作:

    str1[receive] = '\0'; 
    

    緊隨您的mq_receive

  2. 還發送最後的'\0'。您可以通過在您的mq_send中發送len+1字符來完成此操作。

有了這兩個修復程序,您可以擺脫代碼中的兩個memset調用。