use*_*463 25 files socket unix-philosophy
我知道“一切都是文件”是 Unix 的主要概念之一,但是套接字使用内核提供的不同 API(如套接字、sendto、recv 等),而不是像普通的文件系统接口。
“一切都是文件”在这里如何应用?
gol*_*cks 26
套接字使用不同的 API
这并不完全正确。有一些用于套接字的附加功能,但您可以使用,例如,普通read()
和write()
在套接字 fd 上。
“一切都是文件”在这里如何应用?
在涉及文件描述符的意义上。
如果您对“文件”的定义是存储在文件系统中的离散字节序列,那么并非所有内容都是文件。但是,如果您对文件的定义更像是句柄——信息的管道,即 I/O 连接——那么“一切都是文件”开始变得更有意义。这些东西不可避免地涉及字节序列,但它们来自哪里或去哪里可能因上下文而异。
然而,它并不是真正意义上的。一个守护进程是不是一个文件,一个守护进程是一个过程; 但是如果您正在执行IPC,您与另一个进程相关的方法可能会被文件样式实体所缓解。
kub*_*zyk 12
“一切都是文件”只是夸大其词。它在 1970 年代很新颖,是UNIX 的主要区别特征。但这只是一个营销概念,并不是 UNIX 的真正基础,因为这显然不是真的。将所有内容都视为文件是没有好处或不明智的。
CPU是文件吗?您的程序是否读取()CPU 以获取新指令?RAM是文件吗?您的程序是否读取()下一个字节?
那时,有多种操作系统为软盘提供了一个 API,为硬盘提供了不同的 API,为磁带提供了不同的 API,为不同的终端提供了一堆不同的 API,等等。IBM 大型机系统在硬盘上有不同类型的文件,并为每个文件提供了不同的 API,信不信由你!因此,UNIX“它是一个文件”方法,连同“stdin/stdout/stderr”方法,为用户和程序员带来了非常优雅的抽象。
有了网络,这种特殊的抽象就行不通了。没有坏处,只是稍微降低了操作系统的整体优雅和连贯性。但它有效。/dev/myinternetz/www/google/com/tcp/80
您今天在系统上的任何地方看到一个被调用的文件吗?你能用漂亮的 HTML 打开()它,写()一个查询,然后读()答案吗?不?这是因为这种“是一个文件”的抽象对于在网络中进行交互不是很方便。在实践中它不会工作得很好。泄漏抽象定律在起作用。
套接字是文件。您可以在套接字上使用read
and write
:它们相当于调用recv
and send
with flags=0
。你用 关闭它们close
。dup
如果您需要调整文件描述符,您可以和朋友一起移动它们。您可以使用 设置一些标志fcntl
,并在调用 后使用 stdio 缓冲fdopen
。名单还在继续。非常重要的是,您可以调用select
andpoll
任何类型的文件,包括套接字,因此这些函数允许程序阻塞,直到它通过列出文件描述符通过任何方式接收到输入。
某些套接字类型(recv
和send
、shutdown
等)有额外的系统调用,就像设备 ( ioctl
)有额外的系统调用一样。
并非所有文件都有名称,而在有名称的文件中,它们并不总是存在于目录结构中。创建的管道pipe
(例如在外壳管道中)和创建的套接字socketpair
没有名称,但它们仍然是文件。创建的套接字socket
有一个名称,其语法取决于域。此名称在struct sockaddr
tobind
和其他函数中传递。对于 Unix ( AF_UNIX
) 套接字,名称是 a struct sockaddr_un
,它是一个族和一个字符串;根据字符串,这可以是文件名(可以mknod
在许多 unix 变体上创建命名套接字)或不是(抽象名称空间)。对于 IPv4 ( AF_INET
) 套接字,名称为struct sockaddr_in
,包含端口号和 IP 地址,以及protocol
来自socket
调用的 。
如果你stat
是一个socket,你会看到它有一个inode号和其他普通文件的特征,所以我会把它归类为文件系统上的一个文件。例子:
# 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
Run Code Online (Sandbox Code Playgroud)
11/17。Linux (ext3) 的附加信息:套接字有一个 inode(它是磁盘上的 256 字节块)但没有任何数据块(您可以通过提取 inode 并检查数据块指针来验证这一点;或者通过运行 debugfs 'stat' 显示 Blockcount 为 0)。因此,它具有文件元数据(所有者、组、权限等),但磁盘上没有数据内容。这与touch /tmp/foo
块计数为 0的常规空文件 ( ) 相同。在第一种情况下,inode 中的“type”字段显示“socket”;在第二种情况下,它显示“常规文件”。
参考资料:ext2 inode 结构;stat
、dumpe2fs
、 和debugfs
命令。