Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 尝试将数据从子进程服务器传输到其父进程_C_Unix_Pipe - Fatal编程技术网

C 尝试将数据从子进程服务器传输到其父进程

C 尝试将数据从子进程服务器传输到其父进程,c,unix,pipe,C,Unix,Pipe,我正在为我的分布式系统课程做作业。我是C.s.的硕士生,但我的编程专业是.NET,我正在从事一个需要一些相当复杂的Unix知识的项目,这让我很困惑 分配正在实现刷新通道协议API。所以我正在编写一个小函数库,其他应用程序可以实现它来使用刷新通道通信。我对它进行了设置,以便在调用init函数时,它派生一个子进程作为传入消息的服务器。子进程通过管道将传入数据发送给父进程,从而与父进程通信 如果一次发送和接收一条消息,则此功能正常;e、 g 发送->接收->发送->接收->等 但是,如果在进行任何接收

我正在为我的分布式系统课程做作业。我是C.s.的硕士生,但我的编程专业是.NET,我正在从事一个需要一些相当复杂的Unix知识的项目,这让我很困惑

分配正在实现刷新通道协议API。所以我正在编写一个小函数库,其他应用程序可以实现它来使用刷新通道通信。我对它进行了设置,以便在调用init函数时,它派生一个子进程作为传入消息的服务器。子进程通过管道将传入数据发送给父进程,从而与父进程通信

如果一次发送和接收一条消息,则此功能正常;e、 g

发送->接收->发送->接收->等

但是,如果在进行任何接收之前发送了多条消息;e、 g

发送->发送->发送->接收

然后就搞砸了。具体来说,第一条消息接收正确,但当我去接收第二条消息时,程序挂起,需要终止。我在网上做了很多搜索,花了好几个小时都在努力,但没有取得多大进展

整个程序太大,无法在这里显示,但这里是最相关的部分。这是我启动服务器并接收消息的部分。注意这一行

写入(fd[1],缓冲区,(strlen(缓冲区)+1))

--我认为这是一个很好的候选人成为问题的根源,但不知道该怎么做。(尝试了fwrite(),但根本不起作用。)

“+9”用于容纳与要发送的消息一起打包的附加信息,用于刷新通道排序。这也是一个相当粗略的领域,但分配更多的空间以确保额外的安全并没有帮助解决问题

我知道这里有很多无关的东西,对其他函数的引用等等。但问题肯定在于我是如何通过管道传递数据的,所以我的问题的根源应该在那里

提前感谢您的帮助;非常感谢。

这看起来可疑。(数据包中有什么?它们可能是二进制的)数据报的类型定义在哪里

fsize = sizeof(from);
        cc = recvfrom(socketNo, buffer, 2048, 0, (struct sockaddr*)&from, &fsize);
        if (cc < 0) perror("Receive error");
        datagram data = decodeDatagram(buffer);
        if (serials[data.serial] == 0) {
            write(fd[1], buffer, (strlen(buffer)+1)); // <-- ????
            serials[data.serial] = 1;
        }
更新:

如果消息不是以null终止的,则必须显式终止它:

    (if cc == 2048) cc -= 1; 
    buffer [cc] = '\0'; // <<--
    datagram data = decodedatagram(buffer);
    ...
(如果cc==2048)cc-=1;

缓冲区[cc]='\0';//每次通过
while(1)
循环时,您都会分配一个新的
缓冲区--while(1)
为什么?我不明白为什么它是动态分配的,而不是堆栈分配的,我也不明白为什么它会在这个函数之外持续存在。顺便说一句,
strace(1)
在尝试跟踪问题时确实很有帮助。这就像每次系统调用都有一个免费的
printf(3)
行。我不记得我为什么这样做,但显然有一个很好的理由,因为将其更改为堆栈分配会导致编译器发出一些非常不祥的警告。为什么?你认为这与我遇到的问题有关吗?我对你收到的警告很好奇——但这不应该是抓住你的错误,它只是一个简单的内存泄漏。你可能在几十万条信息中都不会注意到。原来这些警告是因为我把零钱弄乱了。在凌晨2:30编辑代码不是一个好主意——我想我会在早上去睡觉,然后再处理一些这个问题;这是作业描述的一部分——对不起,我应该在我的问题中说明这一点。在任何情况下,更改后,它的行为都是相同的——在按顺序发送和接收数据时工作正常,但在用户应用程序接收数据包之前同时发送一组数据包时,它会在尝试检索第二个数据包时挂起。它们可能是字符,但是否以null结尾?发送方是否在每个数据包的末尾显式放置“\0”?此外:如果知道数据包以null结尾,为什么要调用strlen()?这些都是好的观点,但正如我所说的,我将行更改为您建议的行,它没有改变行为。您仍然没有回答“接收到的ascii数据是否以null结尾”的问题?无论如何:我更新了我的答案。是的,是的。这就是为什么它是strlen+1,而不仅仅是strlen。
fsize = sizeof(from);
        cc = recvfrom(socketNo, buffer, 2048, 0, (struct sockaddr*)&from, &fsize);
        if (cc < 0) perror("Receive error");
        datagram data = decodeDatagram(buffer);
        if (serials[data.serial] == 0) {
            write(fd[1], buffer, (strlen(buffer)+1)); // <-- ????
            serials[data.serial] = 1;
        }
            write(fd[1], buffer, cc);
    (if cc == 2048) cc -= 1; 
    buffer [cc] = '\0'; // <<--
    datagram data = decodedatagram(buffer);
    ...
        unsigned pos;
        cc = recvfrom(socketNo, buffer, 2048, 0, (struct sockaddr*)&from, &fsize);
        if (cc < 0) perror("Receive error");
        for pos=0; pos < cc; pos++) {
             if (buff[pos] == 0) break;
             }
        switch (cc-pos) {
        case 0: fprintf (stderr, "No nul byte found in packet: I lose!\n" ); break;
        default: fprintf (stderr, "Spurious nul byte found in the middle of packet\n" );
        case 1: break;
             }

        datagram data = decodeDatagram(buffer);
        if (serials[data.serial] == 0) {
            write(fd[1], buffer, cc);
            serials[data.serial] = 1;
        }