2016-12-09 41 views
1

我試圖通過管道發送一個結構數組。我有一個結構:C - 通過管道發送結構數組

typedef struct visitordata { 
    char name[80]; 
    char email[80]; 
    int id; 
    char reg_time[9]; 
}visitordata; 

然後我做

//... 
//ds is the number of struct entries to be stored 
visitordata* V; 
V = (visitordata*)malloc(ds * sizeof(visitordata)); 

pid_t child = fork(); 
if(child < 0) { 
    perror("Fork error"); 
     exit(1); 
    } 
else if (child > 0) { //parent process 
    write(pipefd[1], &V, sizeof(V)); 
    close(pipefd[1]); 
    fflush(NULL); 
    pause(); 

    sleep(1); 
    pause(); 
    kill(child,SIGTERM);     
    waitpid(child, &status, 0); 
} 
else { //child process 
    visitordata* data; 
    close(pipefd[1]); 

    read(pipefd[0], &data, sizeof(data)); 
    close(pipefd[0]); 
    flush(NULL); 
    for (i = 0; i < ds; ++i) { 
     printf("Received: %s\r\n", data[i].name); 
    } 

    kill(getppid(), SIGUSR1); 
    pause();     
} 

不過,如果我有兩行輸入,接收到的部分只打印出一行字符串「自由」(這是我想想服務器上的用戶名:[email protected]:),然後是Received:,沒有其他任何東西。我究竟做錯了什麼?

編輯

更新的代碼按建議:

visitordata* V; 
V = (visitordata*)malloc(ds * sizeof(visitordata)); 

pid_t child = fork(); 
if(child < 0) { 
    perror("Fork error"); 
     exit(1); 
    } 
else if (child > 0) { //parent process 
    write(pipefd[1], V, ds * sizeof(V)); 
    close(pipefd[1]); 
    fflush(NULL); 
    pause(); 

    sleep(1); 
    pause(); 
    kill(child,SIGTERM);     
    waitpid(child, &status, 0); 
} 
else { //child process 
    visitordata* data; 
    data = (visitordata*)malloc(ds * sizeof(visitordata)); 
    close(pipefd[1]); 

    read(pipefd[0], data, ds * sizeof(data)); 
    close(pipefd[0]); 
    flush(NULL); 
    for (i = 0; i < ds; ++i) { 
     printf("Received: %s\r\n", data[i].name); 
    } 

    kill(getppid(), SIGUSR1); 
    pause();     
} 

現在我的輸出是這樣的:

Received: 0▒:▒0▒:▒ 
Received: 

EDIT 2

更新d

read(pipefd[0], data, ds * sizeof(data)); 

write(pipefd[1], V, ds * sizeof(V)); 

read(pipefd[0], data, ds * sizeof(visitordata)); 

write(pipefd[1], V, ds * sizeof(visitordata)); 

現在我的輸出是:

Received: 0Tɢ0Tɢ 
Received: 
+0

你不應該在'write'和'read'調用中使用'sizeof'。您正在讀取和寫入指針中的字節數(例如4或8) - 您需要傳遞數據的實際長度。 –

+0

你能解釋一下嗎? –

+0

我會盡快添加答案。 –

回答

0

您正在向writeread傳遞不正確的參數。您需要傳遞一個指向實際數據的指針,以及以字節爲單位的數據長度。

所以:

write(pipefd[1], &V, sizeof(V)); 

應該是:

write(pipefd[1], V, ds * sizeof(visitordata)); // note: 2 fixes here 

和類似:

read(pipefd[0], &data, sizeof(data)); 

應該是:

read(pipefd[0], data, ds * sizeof(visitordata)); // note: 2 fixes here also 


另外,如 @Someprogrammerdude所示,您的指針未初始化(它只是一個 野指針)。變化:

visitordata* data; 

到:

visitordata* data = malloc(ds * sizeof(visitordata)); 
+0

好吧,現在我更新了這個,但它仍然不能很好地工作。我會在一分鐘內編輯這個問題。 –

+0

哦,拍攝抱歉,我會修復它! –

-1

這氣味:

寫(pipefd [1],& V,的sizeof(V));

這也許是更好:

寫(pipefd [1],V,的sizeof(V));

接收部分也有問題。在哪裏爲它分配一個緩衝區? visitordata * data;

1

read()write()讀取和寫入請求的字節高達數量。每POSIX standard for write()

write()功能應嘗試寫從 緩衝區指向buf與開放 文件描述符,fildes相關文件nbyte字節。

...

返回值

成功完成後,這些函數將返回實際寫入與fildes關聯的文件的字節數。該數字永遠不會大於nbyte。否則,返回-1並且設置errno來指示錯誤。

你的代碼從不檢查寫入的結果 - 你只是希望它的工作原理。 爲了確保被寫入的字節整個請求數量,你需要的東西是這樣的:

size_t bytesToWrite = ds * sizeof(visitordata); 
size_t totalWritten = 0; 

for (;;) 
{ 
    ssize_t bytesWritten = write(pipefd[1], V + totalWritten, 
     bytesToWrite - totalWritten); 
    if (bytesWritten <= 0) 
    { 
     break; 
    } 

    totalWritten += bytesWritten; 
} 

您需要處理read()類似。

+0

我的輸出仍然是內存垃圾:/ –

+0

@lte__你在'read()'方面做了同樣的事嗎?你是否正在運行一個調試器來查看實際寫入和讀取的字節數?您還可以使用類似'fprintf(stderr,...);'的代碼將調試輸出添加到您的代碼中,以找出您的代碼實際上在做什麼。 –

+0

是的,我也是爲了閱讀而做的。我會嘗試以某種方式調試它。 –