C通过命名管道发送分配的字符串--linux

时间:2017-05-10 12:52:22

标签: c linux

我想通过命名管道发送已分配的字符串,而不是简单的字符数组。

我收到了以下代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>

int main()
{
    int pid, fd;
    fd = mkfifo("fifo.ftc", S_IRUSR | S_IWUSR);
    pid = fork();

    char* send, * recieve;

    if(pid == 0) {
        recieve = malloc(100);
        fd = open("fifo.ftc", O_RDONLY);
        read(fd, recieve, sizeof(recieve));
        close(fd);
        printf("%s\n", recieve);

        send = malloc(100);
        send = "This text was sent by child!";
        fd = open("fifo.ftc", O_WRONLY);
        write(fd, send, sizeof(send));
        close(fd);

        free(recieve);
        free(send);

    } else if(pid > 0) {
        send = malloc(100);
        send = "This text was sent by parent!";
        fd = open("fifo.ftc", O_WRONLY);
        write(fd, send, sizeof(send));
        close(fd);

        recieve = malloc(100);
        fd = open("fifo.ftc", O_RDONLY);
        read(fd, recieve, sizeof(recieve));
        close(fd);
        printf("%s\n", recieve);

        unlink("fifo.ftc");

        free(send);
        free(recieve);
    }
}

作为输出,我总是接受:

This tex
This tex

看起来它不会打印出整个字符串。如何收到来自父母和孩子的全部信息?

2 个答案:

答案 0 :(得分:3)

您的代码中存在多个错误。

  1. 您必须记住,readwrite并不能保证他们能够有效地读取或写入您告诉他们的字节数。

    从Linux编写手册页:

      

    <强>概要

         

    #include&lt; unistd.h&gt;

         

    ssize_t write(int fd,const void * buf,size_t count);

         

    <强>描述

         

    write()写入从缓冲区指向buf的计数字节到   文件描述符fd引用的文件。 字节数   如果 ,写入可能少于计数,例如,不足   底层物理介质上的空间,或RLIMIT_FSIZE资源   遇到限制(参见setrlimit(2)),或者呼叫被中断   写入少于count个字节后由信号处理程序。 (看到   也管(7)。)

    它们返回它们已读取或写入的字节数,因此您必须将它们的返回值存储在变量中并相应地处理它。您通常将它们包装在一个循环中,保留一个计数器,该计数器累积读取/写入的字节数,并在达到原始缓冲区大小时退出循环,或者返回错误值。

    < / LI>
  2. 如@wildplasser在评论中所述,您滥用sizeof运算符。执行char *foo; sizeof foo;时,结果大小不是foo指向的字符串的大小,而是char指针类型的大小(64位体系结构中的8个字节,32位中的4个字节)。您应该使用strlen(foo)代替。

答案 1 :(得分:1)

@jweyrich已经回答了你问题的要点。但是,您可能会考虑其他一些要点......

在开始使用该语言时,C语言中的字符串赋值有时会出现混乱,因为有时会进行分配,例如:

send = "This text was sent by parent!";

会工作,而其他人则不会。它适用于这种情况,因为代码中的变量send是作为指针创建的。请记住,如果它是作为一个数组创建的,那么使用=运算符进行赋值的唯一时间就是在初始化期间。必须以不同方式对C字符串的char array形式进行后初始化分配。通常,字符串函数(strcpystrcatsprintf等)用于修改或赋值给字符串;例子:

//string literal used to initialize
char send[100] = "This text was sent by parent!"; //works

//initialized with nul terminator
char send[100] = '\0';
//post initialization statements:
strcpy(send, "This text was sent by parent!");//works
strcat(send, "This text was sent by parent!");//works
sprintf(send, "%s", "This text was sent by parent!");//works

但:

send = "This text was sent by parent!"; //does not work;

More on strings here

此外,建议您始终检查malloc()的返回以确保确实已分​​配内存:

send = malloc(100);
if(!send) return -1; //check return of malloc
send = "This text was sent by parent!";

另一点:因为recieve是指针,它的大小将是包含其地址所需的字节数,对于32位目标可能是4个字节,对于64位是8个字节目标。所以声明:

read(fd, recieve, sizeof(recieve));

很可能告诉读取读取4或8个字节,这可能不是您所期望的。将此行更改为:

read(fd, recieve, 100);