我知道“一切都是文件”是Unix的主要概念之一,但是套接字使用内核提供的不同API(如socket、sendto、recv等),而不像普通的文件系统接口。
“一切皆文件”在这里如何应用?
答案1
套接字使用不同的 API
这并不完全正确。还有一些与套接字一起使用的附加函数,但您可以使用例如普通函数read()
和write()
套接字 fd。
“一切皆文件”在这里如何应用?
从某种意义上讲,涉及文件描述符。
如果“文件”的定义是存储在文件系统中的离散字节序列,那么并非所有内容都是文件。然而,如果您对文件的定义更像是句柄——信息的管道,即 I/O 连接——那么“一切都是文件”就开始变得更有意义。这些东西不可避免地涉及字节序列,但它们来自或去往的地方可能根据上下文而不同。
然而,这并不是字面意思。 A守护进程守护进程不是文件,而是进程;但如果你正在做工控机文件样式实体很可能会减轻您与另一个进程相关的方法。
答案2
“一切都是文件”只是一种夸张的说法。它曾是20世纪70年代的小说曾是UNIX 的一个主要区别特征。但这只是一个营销概念,并不是 UNIX 的真正基础,因为这显然不是事实。将所有内容都视为文件是没有好处或不明智的。
CPU是文件吗?你的程序是否通过 read() CPU 来获取新指令? RAM是文件吗?你的程序是否 read() 下一个字节?
当时,有多种操作系统为您提供了一种针对软盘的 API、针对硬盘的不同 API、针对磁带的不同 API 以及针对不同终端的一堆不同 API 等等。 IBM 大型机系统的硬盘上有不同类型的文件,并且为每个文件提供了不同的 API,无论您相信与否!因此,UNIX“它是一个文件”方法与“stdin/stdout/stderr”方法一起,为用户和程序员带来了非常优雅的抽象。
对于网络来说,这种特殊的抽象就行不通了。这并没有什么坏处,只是操作系统的整体优雅性和连贯性稍差一些。但它有效。您/dev/myinternetz/www/google/com/tcp/80
今天在系统中的任何地方看到有一个被调用的文件吗?你能 open() 它, write() 一个查询,然后 read() 漂亮的 HTML 答案吗?不?这是因为这种“是文件”抽象对于网络交互来说不太方便。在实践中效果不太好。泄漏抽象定律在行动中。
答案3
套接字是文件。您可以在套接字上使用read
and write
:它们相当于调用recv
和send
和flags=0
。你用以下命令关闭它们close
。您可以使用以下命令移动它们dup
如果您需要打乱文件描述符,请和朋友们一起。你可以设置一些标志fcntl
,并在调用后使用stdio缓冲fdopen
。这样的例子还在继续。非常重要的是,你可以打电话select
和poll
任何类型的文件,包括套接字,因此这些函数允许程序阻塞,直到它通过任何方式简单地通过列出文件描述符接收输入。
对于某些套接字类型有额外的系统调用(recv
和send
,shutdown
等),就像设备有一个额外的系统调用(ioctl
)。
并非所有文件都有名字,而在那些确实存在的目录中,它们并不总是存在于目录结构中。创建的管道pipe
(例如在 shell 管道中)和由以下创建的套接字socketpair
没有名字,但它们仍然是文件。套接字创建者socket
有一个名称,其语法取决于域。该名称通过struct sockaddr
to传递bind
和其他功能。对于 Unix ( AF_UNIX
) 套接字,名称是struct sockaddr_un
,这是一个族和一个字符串;根据字符串,这可以是文件名(可以在mknod
许多 UNIX 变体上创建命名套接字),也可以不是文件名(抽象命名空间)。对于 IPv4 ( AF_INET
) 套接字,名称是struct sockaddr_in
,包含端口号和 IP 地址,以及protocol
来自socket
呼叫的 。
答案4
如果你是stat
一个套接字,你会看到它有一个索引节点号和常规文件的其他特征,所以我将它分类为文件系统上的文件。例子:
# file live
live: socket
# stat live
File: `live'
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: fc03h/64515d Inode: 198817 Links: 1
Access: (0660/srw-rw----) Uid: (23129/ icinga) Gid: (23130/icinga-cmd)
Access: 2014-11-07 09:27:59.000000000 -0800
Modify: 2014-11-05 09:27:03.000000000 -0800
Change: 2014-11-05 09:27:03.000000000 -0800
11/17。 Linux (ext3) 的附加信息:套接字有一个索引节点(磁盘上的 256 字节块),但没有任何数据块(您可以通过提取索引节点并检查数据块指针来验证这一点;或者通过运行 debugfs 'stat' 显示块计数为 0)。因此,它具有文件元数据(所有者、组、权限等),但磁盘上没有数据内容。这与块计数为 0 的常规空文件 ( ) 相同。touch /tmp/foo
在第一种情况下,inode 中的“type”字段显示“socket”;在第一种情况下,inode 中的“type”字段显示“socket”;在第一种情况下,inode 中的“type”字段显示“socket”。在第二种情况下,它显示“常规文件”。
参考:ext2 索引节点结构; stat
、dumpe2fs
、 和debugfs
命令。