Unix Internet套接字文件吗?


23

我知道“一切都是文件”是Unix的主要概念之一,但是套接字使用内核提供的不同API(例如套接字,sendto,recv等),而不是普通的文件系统接口。

这个“一切都是文件”在这里如何应用?

Answers:


26

套接字使用不同的API

并非完全如此。套接字还有一些其他功能,但是您可以使用,例如,普通read()write()套接字fd。

这个“一切都是文件”在这里如何应用?

在某种意义上涉及文件描述符。

如果您对“文件”的定义是存储在文件系统中的离散字节序列,则并非所有内容都是文件。但是,如果您对文件的定义更具说服力(信息的管道,即I / O连接),那么“一切都是文件”就变得更有意义了。这些事情不可避免地涉及字节序列,但是它们的来源或去向可能因上下文而异。

但是,这并不是字面上的意图。一个守护进程是不是一个文件,一个守护进程是一个过程; 但是,如果您正在执行IPC,则文件样式实体很可能会减轻与另一进程相关的方法。


5
我要说的“一切都是文件”的准确改写应该是“所有接口都通过文件”。您通过文件(stdin / out / err,/ proc / $ pid等)与进程进行交互。您通过文件(套接字/文件描述符)与网络进行交互。您通过文件(/ dev / mouse)与鼠标进行交互。
帕特里克

我曾经通过从/ proc中打开它来克隆套接字句柄。
2014年

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打开()它,写()一个查询,然后读()一个答案吗?没有?这是因为这种“是文件”的抽象对于在网络上进行交互不是很方便。在实践中它不会太好用。泄漏抽象定律在行动中。


9
有趣的事实:bash的某些版本将允许您打开/dev/tcp/www.google.com/80。它不是一个实际的文件-bash只是伪造它。
user253751 2014年

2
@immibs:更重要的是,有可能制作一个实际实现该目标的文件系统。
2014年

我想你可以阅读/dev/mem/dev/kmem如果你想要的。
杰森C

4
请注意,计划9更进一步,实际上,网络协议是通过伪文件系统寻址的,以实现/ dev / myinternetz / www / google / com / tcp / 80示例的作用(当然具有不同的路径)。此外,物理ram实际上确实像文件一样工作,将ram映射到虚拟地址空间就像将文件映射到虚拟地址一样。(基于这个想法实现了malloc)。

1
计划9除了将“一切都是网络透明的”之外,将“一切都是文件”发挥到了极致。例如,不需要NAT,您只需在本地计算机上安装路由器的TCP / IP堆栈(只是网络透明文件(系统)),然后直接从路由器发送数据包即可。
约尔格W¯¯米塔格

7

套接字是文件。您可以在套接字上使用readwrite:它们等效于recvsend一起调用和flags=0。您用关闭它们closedup如果需要重新整理文件描述符,则可以与和朋友一起移动它们。您可以使用设置一些标志fcntl,并在调用后使用stdio缓冲fdopen。清单继续。非常重要的是,您可以在任何类型的文件(包括套接字)上调用selectpoll,因此这些函数允许程序阻塞,直到它通过列出文件描述符的任何方式接收到输入为止。

某些套接字类型(recvsendshutdown等)还有额外的系统调用,例如设备(ioctl)也有额外的系统调用。

并非所有文件都具有名称,在具有名称的文件中,它们并不总是存在于目录结构中。通过创建管道pipe通过创建(例如,在一个管道)和插座socketpair没有名字,但他们仍然文件。创建的套接字socket的名称取决于域。这个名字是在通过struct sockaddrbind等功能。对于Unix(AF_UNIX)套接字,名称是a struct sockaddr_un,它是一个家族和一个字符串。根据字符串的不同,它可以是文件名(可以mknod在许多unix变体上创建命名的套接字),也可以不是文件名(抽象名称空间)。对于IPv4( AF_INET)插槽,名字是一个struct sockaddr_in,包含端口号和IP地址,以及protocolsocket电话。


7

如果您使用的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)相同。在第一种情况下,索引节点中的“类型”字段显示为“套接字”;在第二种情况下,它显示“常规文件”。

参考:ext2 inode结构statdumpe2fsdebugfs命令。


1
我想说,只有可以运行file或运行的东西才能stat使它成为文件。
凯文
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.