创建替换stdin的文件描述符(在select()中)

时间:2017-03-15 11:37:38

标签: c file-descriptor

考虑到在没有键盘输入的情况下与多客户端Unix域套接字进行通信,我想创建一个替换stdin的文件描述符。

使用多客户端套接字时,您必须将stdin的文件描述符(带有FD_SET(0, &readfds)的0)添加到readfds才能发送键盘输入(FD_ISSET(0, &readfds))到服务器。由于我不想每次启动我的客户端时编写,我想用自定义的文件描述符替换它(通过从另一个程序写入此文件)。

我检查了Create a file descriptor以创建两个程序:

写入文件描述符的那个:

int main() {
    char buffer[] = "test";
    int fd = open("sample.dat", O_WRONLY | O_CREAT, 0666);
    dup2(fd, 5);

    if(write(5, buffer, 4) < 0)
        fprintf(stderr, "write %s\n", strerror(errno));

    close(5);    
    return 0;
}

另一个从中读取的内容:

int main() {
    char buffer[4];
    int fd = open("sample.dat", O_RDONLY);
    dup2(fd, 5);

    for(;;) {
        if(read(5, buffer, 4) < 0)
            fprintf(stderr, "read %s\n", strerror(errno));

        printf("%s\n", buffer);
        sleep(1);
    }

    return 0;
}

我的问题是:是否可以将此文件描述符设为stdin?我的意思是实际上我的第二个程序无休止地读取“test”,因为(当然)sample.dat仍然包含“test”但我想在读取后删除它。

3 个答案:

答案 0 :(得分:0)

是。您可以使用管道:https://linux.die.net/man/2/pipe

或者FIFO:https://linux.die.net/man/3/mkfifo 使用FIFO将在文件系统中创建一个文件,该文件可以由客户端和服务器进程打开以进行通信。

答案 1 :(得分:0)

如果我理解正确,您希望与只能读取标准输入的程序进行通信。 您可以通过两种方式在stdin中编写:第一种方法是使用键盘,第二种方法是使用write()

#include <unistd.h>
#include <string.h>

int         main(void)
{
    char    *s = "what you want to write";
    write(STDIN_FILENO, s, strlen(s));
    return (0);
}

这个程序将在stdin上写,就像你用键盘写的一样。此外,您将看到在命令行界面上打印的字符串。

答案 2 :(得分:0)

问题不在于你在&#34; test&#34;经常,您没有正确处理对read()的调用。虽然您正在检查它是否未返回错误,但您还没有看到已读取了多少字节。read()没有空终止读取的字符串,所以你应该存储返回值并使用它来将NUL放入缓冲区。否则,由于缓冲区中没有任何内容发生变化,它看起来就好像你一遍又一遍地重读同一文本。

    int err=read(fd, buffer, 4);
    if(err < 0)
        {
        fprintf(stderr, "read %s\n", strerror(errno));
        }
    else
        {
        buffer[err]='\0';
        }

如果你做了这个改变,你会发现你只读过&#34; test&#34;一次又一次之后你就不再阅读了。

注意:您不需要调用dup2() - 这只是为了将文件描述符复制到已知值。您可以在调用读/写数据时使用fd