繁体   English   中英

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

[英]Create file descriptor that replaces stdin (in select())

考虑到无需键盘输入即可与多客户端Unix域套接字通信,我想创建一个替换stdin的文件描述符。

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

我签出了创建文件描述符以创建两个程序:

写入文件描述符的一个:

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”,但是一旦读取,我想将其删除。

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

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

如果我理解正确,您想与只能在标准输入上阅读的程序进行通讯。 您可以使用两种方法在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上编写。 此外,您还将看到在命令行界面上打印的字符串。

问题不在于您不断读取“测试”,而是您没有正确处理对read()的调用。 在检查它没有返回错误的同时,也没有看到已读入多少字节read()不会对读入的字符串进行空终止,因此您实际上应该存储返回值并使用它将NUL放入缓冲区。 否则,由于缓冲区中的任何内容都没有变化,因此好像您要一遍又一遍地重新读取相同的文本。

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

如果进行此更改,您会发现您只阅读过一次“测试”,此后您将不再阅读任何内容。

注意:您不需要调用dup2() -仅用于将文件描述符复制到已知值。 您可以直接在呼叫中使用fd来读取/写入数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM