2016-12-09 30 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

是的,我也是为了阅读而做的。我会尝试以某种方式调试它。 –