C - 通过管道发送struct数组

时间:2016-12-09 15:50:41

标签: c arrays struct pipe

我正在尝试通过管道发送一组结构。我有一个结构:

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();                
}

但是,如果我有两行用于输入,则Received部分仅打印出一行,其中字符串为“free”(我认为是从服务器上的用户名编写的:freeze@server:)然后是{{ 1}}没有别的。我做错了什么?

修改

根据建议更新了代码:

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();                
}

编辑2

更新了

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

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));

3 个答案:

答案 0 :(得分:2)

read()write()读取最多请求的字节数。根据{{​​3}}:

  

write()函数将尝试从中写入 nbyte个字节   buf指向与open相关联的文件的缓冲区   文件描述符fildes

     

...

     

返回值

     

成功完成后,这些函数将返回实际写入与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()

答案 1 :(得分: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所述,您data指针未初始化(它只是野指针)。改变:

visitordata* data;

为:

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

答案 2 :(得分:-1)

这闻起来:

写(pipefd [1],&amp; V,sizeof(V));

也许这更好:

写(pipefd [1],V,sizeof(V));

接收部分也存在问题。在哪里为它分配缓冲区? visitordata * data;