繁体   English   中英

在 linux 下的 C 中创建无缓冲文件描述符

[英]Create unbuffered file descriptor in C under linux

出于测试目的,我想在 C 中的 linux 下创建一个完全无缓冲的文件描述符。它应该有一个读取和一个写入端。 它可以是以下之一:

  • 先进先出
  • pipe
  • 本地或 tcp 套接字
  • 使用标准输入/标准输出
  • 虚拟 kernel 文件(例如 /proc/uptime)

(我认为列表已完成)

因此调用 write() 会将内容直接复制到 read() 提供的缓冲区中。

这甚至可能吗?或者两者之间总是有一个缓冲区? 如果有可能比如何实现这一目标?

这是我的代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    int len = 0;
    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, 4);
    struct sockaddr_in serv_addr = {}; 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(80); 
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
    connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    char buf;
    read(fd, &buf, 1);
    return 0;
}

但是数据并没有直接读入buf 原因是我的 setsockopt() 调用并没有真正将接收缓冲区设置为零。 相反,它被设置为最小值 256,可以在手册页 socket(7) 上阅读。

所以调用 write() 会将内容直接复制到 read() 提供的缓冲区中

这有可能吗

否。仅在使用splice()sendfile()或类似系统调用时。 这在很大程度上取决于实际文件描述符所指的内容。

两者之间总是有缓冲区吗? 如果有可能比如何实现这一目标?

不,您可以:

  • 先进先出 / pipe
    • 使用splice()sendfile()
    • 使用共享 memory 代替
  • 本地或 tcp 套接字
    • 打开/proc/mem并直接写入硬件。
    • 编写/使用执行相同操作的特定 kernel 设备驱动程序
    • (我不知道,但也许copy_from_user允许直接复制到硬件地址)
  • 使用标准输入/标准输出
    • 文件描述符只是一个指针——stdin 和 stdout 都可以指向 tcp 套接字、fifo 或其他任何东西
    • 这取决于文件描述符指的是什么
  • 虚拟 kernel 文件(例如 /proc/uptime)
    • 取决于实际的“虚拟 kernel 文件”实现
    • 大多数(如果不是全部)实现搜索/支持部分读取或使用struct seq_file ,它必须有一个中间缓冲区。

暂无
暂无

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

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