gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 23:55:43 24 4
gpt4 key购买 nike

我正在为分布式系统类(class)布置作业。我是 C.S. 的硕士生,但我的编程专长是 .NET,而且我正在从事一个需要一些相当复杂的 Unix 知识的项目,这让我很困惑。

作业是实现刷新 channel 协议(protocol) API。所以我正在编写一个小函数库,其他应用程序可以实现它以使用刷新 channel 通信。我已将其设置为在调用 init 函数时派生一个子进程作为传入消息的服务器。子进程通过管道将传入数据发送到父进程,从而与父进程通信。

如果一次发送和接收一条消息,这就可以正常工作;例如,

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

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

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

然后就乱了。具体来说,第一条消息接收正确,但是当我去接收第二条消息时,程序挂了,需要杀掉。我在网上进行了大量搜索,并为此埋头苦干了几个小时,但没有取得太大进展。

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

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

-- 我认为这是问题根源的一个很好的候选者,但不确定如何做不同的事情。 (试过 fwrite() 但根本不起作用。)

    fd = malloc(2 * sizeof(int));
int nbytes;
if (pipe(fd) < 0) {
perror("Could not create pipe");
return -1;
}

pID = fork();

if (pID < 0) {
perror("Failed to fork");
return -1;
} else if (pID == 0) { // child
close(fd[0]); // close input side of pipe
int cc;
int fsize;
struct sockaddr_in from;
int serials[500];
int i;
for (i = 0; i < 500; i++) serials[i] = 0;

char buffer[2048];

while (1) {
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;
}
}
} else { // parent
close(fd[1]); // close output side of pipe
return 0;
}

(“serials”数组是为了不转发重复的消息,因为消息会被多次发送以提高可靠性。我知道这个数组的固定大小不是好的做法,但是这个分配的测试不会发送那个许多消息,因此在这种情况下没问题。)

接收函数的开头是这样的:

int fRecv(int* id, char* buf, int nbytes) {

checkDatagramTable(*id);

char* tbuf = malloc((nbytes + 9) * sizeof(char));
int rbytes = read(fd[0], tbuf, nbytes + 9);

“+9”用于容纳与要发送的消息一起打包的附加信息,以用于刷新 channel 排序。这也是一个非常粗略的区域,但分配更多空间以更加确定并没有帮助解决这个问题。

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

预先感谢您的协助;非常感谢。

最佳答案

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

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

此外,建议使用“sizeof buffer”而不是“2048”。

更新 2:您可以通过以下方式测试数据包中的字符串是否真的以 null 结尾:

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

关于c - 尝试将数据从子进程服务器传输到其父进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8200000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com