为什么 TCP/IP 套接字被认为是“打开的文件”?

Mik*_*e B 35 networking files socket

我需要一些帮助来理解我确信 Linux 中的一个基本概念:打开文件的限制。具体来说,我对为什么打开的套接字可以计入系统上“打开文件”的总数感到困惑。

有人可以详细说明原因吗?我知道这可能可以追溯到 Linux 中的整个“一切都是文件”原则,但任何其他细节都将不胜感激。

Gre*_*ill 42

“打开文件”的限制不仅仅针对文件。这是对单个进程一次可以使用的内核句柄数量的限制。从历史上看,程序通常唯一会打开很多文件的是文件,因此这被称为打开文件数量的限制。有一个限制可以帮助防止进程打开大量文件并意外忘记关闭它们,这最终会导致系统范围的问题。

套接字连接也是内核句柄。因此相同的限制适用于相同的原因 - 进程可能会打开网络连接并忘记关闭它们。

正如评论中所指出的,内核句柄在类 Unix 系统中传统上称为文件描述符

  • “内核句柄”是 Windows 术语。您更愿意参考“文件描述符”,这就是 Unix 和 Linux 通常如何调用这些实体。 (23认同)
  • 这个答案对冲太多了。套接字*是*文件。它们通过 `read`/`write` 接口提供对字节流的访问,这是成为文件的核心意义。 (13认同)
  • @WumpusQ.Wumbley,但是随后您对它们进行了 `shutdown(2)` 系统调用,而不是在文件上,并且您无法使用 `cat` 从套接字中读取数据——这就是创建 `netcat` 的原因。我会说(幸运的是)类 Unix 内核中的套接字在 I/O 方面的行为类似于文件,但相似之处就在那里。(老实说,我也想听听有 Plan 9 经验的人的意见,因为我听说他们比传统的 unice 更能统一这些东西)。 (4认同)
  • “一切都是文件”的想法意味着“文件”是一种具有许多子类型的抽象数据类型。除了所有文件支持的基本内容之外,大多数子类型还支持额外的方法。插座有很多附加功能。块设备和常规文件都有搜索。目录真的很奇怪(写入不起作用,如果读取有效,则没有用)。额外方法的存在并不意味着这些东西不是我们称之为“文件”的一般事物类别的一部分。 (4认同)

Stu*_*aie 31

究其原因,为什么TCP / IP套接字使用文件描述符的是,当套接字接口最初设计和实施(在BSD Unix的,于1983年),它的设计者认为,网络连接是类似于一个文件-你可以readwriteclose两个,并且它非常符合 Unix 的“一切都是文件”的理念。

其他 TCP/IP 网络堆栈实现不一定与其操作系统的文件 I/O 子系统集成,例如MacTCP。但是因为 BSD 套接字接口是如此流行,甚至这些其他实现也选择复制套接字 API 及其类 Unix 函数,所以你得到了“文件描述符”,仅用于 TCP/IP 通信,在其他系统上没有有文件描述符。

你问题的另一部分是为什么有限制?这是因为实现文件描述符查找表的最快方法是使用数组。从历史上看,限制是硬编码到内核中的。

这是 Unix 版本 7(1979)中的代码,每个进程硬编码限制为 20 个文件描述符:

相比之下,Linux 为进程的文件描述符表动态分配空间。绝对限制默认为 8192,但您可以将其设置为您喜欢的任何值。我的系统在/proc/sys/fs/file-max.

尽管Linux不再有绝对限制,但我们不想让程序疯狂,所以管理员(或分发打包者)通常会设置资源限制。看看/etc/security/limits.conf,或者跑ulimit -n


Lig*_*bit 7

文件不仅仅是磁盘或内存中的文件;它们是数据流,这只是其中的两个例子。

远程端点是第三个示例,您可以与使用套接字的端点进行交互。

  • 欢迎来到 U&L.SE。我喜欢这个答案。 (2认同)