C中的进程间通信

Posted

技术标签:

【中文标题】C中的进程间通信【英文标题】:Inter-Process Comunication in C 【发布时间】:2016-05-30 00:34:25 【问题描述】:

我正在使用管道进行 IPC 练习。协议如下:

    client(child) 从标准输入读取文件名 客户端通过管道向服务器发送文件名 服务器(父)从管道中读取文件名 服务器获取文件信息(stat sys call) 服务器通过管道向客户端发送文件信息。 客户端从管道读取文件信息并输出到标准输出

我在最后一步遇到问题,我不知道如何正确发送此信息。目前客户端的输出是垃圾。这是代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#define BUFSIZE 1024

int main()

    int fd1[2], fd2[2], pid, n;
    char buf[BUFSIZE];
    pipe(fd1);
    pipe(fd2);
    if ((pid = fork()) == 0)
    
        close(fd1[0]);
        close(fd2[1]);
        read(STDIN_FILENO, buf, BUFSIZE); // 1. client(child) reads file name from stdin
        int len = strlen(buf);
        buf[len - 1] = '\0';
        write(fd1[1], buf, len); // 2. client sends file name over pipe to server
        while ((n = read(fd2[0], buf, BUFSIZE)) > 0)
        
            write (STDOUT_FILENO, buf, n); // 6. client reads file info from pipe and outputs to stdout
        
    
    else
    
        struct stat st;
        close(fd1[1]);
        close(fd2[0]);
        read(fd1[0], buf, BUFSIZE); // 3. server (parent) reads file name from pipe
        stat(buf, &st); // 4. server obtains information about the file (stat sys call)
        write(fd2[1], (void *)st.st_size, sizeof(st.st_size)); // 5. server file information over pipe to client.
        write(fd2[1], (void *)st.st_atime, sizeof(st.st_atime));
    
    return 0;

更新

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#define BUFSIZE 1024

int main()

    int fd1[2], fd2[2], pid;
    size_t n;
    char buf[BUFSIZE];
    pipe(fd1);
    pipe(fd2);
    if ((pid = fork()) == 0)
    
        close(fd1[0]);
        close(fd2[1]);
        n = read(STDIN_FILENO, buf, BUFSIZE - 1); // 1. client(child) reads file name from stdin
        buf[n] = '\0';
        write(fd1[1], buf, n); // 2. client sends file name over pipe to server
        while ((n = read(fd2[0], buf, BUFSIZE)) > 0)
        
            if ((write (STDOUT_FILENO, buf, n)) != n) // 6. client reads file info from pipe and outputs to stdout
            
                perror("client: write error\n");
            
        
    
    else
    
        struct stat st;
        close(fd1[1]);
        close(fd2[0]);
        read(fd1[0], buf, BUFSIZE); // 3. server (parent) reads file name from pipe
        stat(buf, &st); // 4. server obtains information about the file (stat sys call)
        if (write(fd2[1], (void *)st.st_size, sizeof(st.st_size)) != sizeof(st.st_size)) // 5. server sends file information over pipe to client
        
            perror("server: write error\n");
         
        if (write(fd2[1], (void *)st.st_atime, sizeof(st.st_atime)) != sizeof (st.st_atime))
        
            perror("server: write error\n");
        
    
    return 0;

【问题讨论】:

你需要dupstdin。 【参考方案1】:

你不能在这里使用strlen()。您应该改用来自read() 的返回值。

read() 之后buf 中的数据只是一个字节序列,如果在序列末尾添加一个'\0' 字节,它可能会变成一个字符串。由于它不存在,因此调用 strlen() 会调用 未定义的行为,因此无论您之后做什么,它都不会按预期运行。

strlen() 可以被认为是

size_t 
strlen(const char *const string)

    size_t length;
    length = 0;
    while (string[length] != '\0')
        ++length;
    return length;

你应该避免这样的事情的一个原因

for (size_t i = 0 ; i < strlen(string) ; ++i) ...

特别是因为您可以使用类似于上述strlen() 实现中的循环。

改用来自read() 的返回值

ssize_t read_length;
read_length = read(STDIN_FILENO, buf, sizeof(buf) - 1);

如果你想让它成为一个有效的字符串,你可以将它传递给任何str* 函数,只需

buf[read_length] = '\0';

例如,不要忘记检查错误 read_length != -1

【讨论】:

为什么?用户输入中会有一个 '\n',因此 strlen 应该可以正常工作。 不,'\n' 不会使 strlen() 停止。 从用户接收的字节序列中没有'\0' 它来自stdin,所以我怀疑是否存在。此外,在不捕获返回值的情况下调用read() 非常糟糕。 我做了一些改变。仍然有问题,现在我可以捕获错误。这是什么原因?

以上是关于C中的进程间通信的主要内容,如果未能解决你的问题,请参考以下文章

Linux C语言高级编程之使用消息队列实现进程间通信!重点内容!!!

C中进程间通信中的数据流控制[关闭]

请教一个Linux下C语言的进程间的信号问题

C中的进程间通信

Linux C与C++一线开发实践之四 Linux进程间的通信

Linux C与C++一线开发实践之四 Linux进程间的通信