写pid到fifo - C.

时间:2012-12-18 15:16:51

标签: c unix pipe pid fifo

我有两个C文件,server.c和client.c。服务器必须创建一个fifo文件并不断读入它,等待输入。客户端获取其PID并将PID写入fifo。 这是我首先启动的服务器文件:

int main(){
  int fd;
  int fd1;
    int bytes_read;
    char * buffer = malloc(5);
    int nbytes = sizeof(buffer);

    if((fd = mkfifo("serverfifo",0666)) == -1) printf("create fifo error");
    else printf("create fifo ok");

    if ((fd1 = open("serverfifo",O_RDWR)) == -1) printf("open fifo error");
    else{
        printf("open fifo ok"); 
        while(1){
            bytes_read = read(fd,buffer,nbytes);
            printf("%d",bytes_read);
            }
        }

return(0);
}

我的客户档案:

int main(){

    int fd;
    int pid = 0;
    char *fifo;
    int bytes;

    if ((pid = getpid()) == 0)  printf("pid error");
    char pid_s[sizeof(pid)];
    sprintf(pid_s,"%d",pid); 


   if ((fd = open ("serverfifo",O_RDWR)) == -1)printf("open fifo error");
   else {
    printf("open fifo ok");

        bytes = write(fd,pid_s, sizeof(pid_s));
        printf("bytes = %d",bytes);

   }

    close(fd);
return(0);
}

我得到的两个主要问题是:当我将pid写入文件时,它返回我写的字节数,所以它看起来没问题但是当我检查fifo文件的属性时它说0字节。第二个问题是读取不起作用。如果我在它显示之前做了一个printf,但是在它没有并且读取没有返回任何东西之后它就会冻结。 我意识到网站上有很多类似的帖子,但我找不到任何有帮助的帖子。 我正在使用Ubuntu和GCC编译器与CodeBlocks。

2 个答案:

答案 0 :(得分:3)

这里有很多不妥之处

char pid_s[sizeof(pid)];
sprintf(pid_s,"%d",pid); 

sizeof(pid)返回pid值的大小,而不是其字符串表示形式,即sizeof(int),它是4或8,具体取决于您的体系结构。然后,您继续打印它。如果这有效,它只能运气(你在64位机器上)。正确的方法是,如果你选择这样做,就是分配一个适当大的缓冲区,并使用snprintf确保你不会溢出。 PID适合5位数,所以这样的事情会做:

char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);

当然,您可以一起跳过此步骤并发送pid的原始字节

write(fd, (void*)&pid, sizeof(pid))

现在在服务器中你犯了类似的错误:

char * buffer = malloc(5);
int nbytes = sizeof(buffer);

sizeof(buffer)再次返回4或8,但是你分配了5个字节,正确的方法是这样做,如果你想在堆上分配(使用malloc),是这样的:

char* buffer = malloc(8);
int nbytes = 8;

或者你可以在堆栈上分配:

char buffer[8];
int nbytes = sizeof(buffer);

sizeof有点神奇,因为如果你传入一个数组,它会返回数组的大小(8 * 1)。

当你正在阅读时,你读了5个字节,这可能是不够的(因为你因为早期的bug而写了8个字节),所以它不会完成。你应该读这样的

int pid;
read(fd, (void*)&pid, sizeof(pid));

另外,如果你真的要读写字符串,你可以这样做:

// client
char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);
write(fd, pid_s, sizeof(pid_s));

// server
char pid_s[8];
read(fd, pid_s, sizeof(pid_s));

另请注意,read可能会返回少于写入的内容,您需要再次调用它以继续阅读...

答案 1 :(得分:0)

这段代码中有很多错误...... 首先,sizeof不是这样的。 为什么要序列化pid?

这是错误的:

char pid_s[sizeof(pid)];

123456是一个int,它不适合这个大小为4的数组,只能打印3个字符...

因为你试图序列化pid你不知道要读取的预期大小,除非你采取最坏的情况并为'\ 0'写10 + 1 ......

相关问题