JEP 380:Unix 域套接字通道
总结
在 java.nio.channels
包中,为 socket channel 和 server-socket channel API 添加 Unix-domain (AF_UNIX
) socket 支持。扩展 继承通道机制 以支持 Unix-domain socket 通道和服务器 socket 通道。
目标
Unix 域套接字用于同一主机上的进程间通信(IPC)。在大多数方面,它们与 TCP/IP 套接字相似,不同之处在于它们通过文件系统路径名寻址,而不是通过互联网协议(IP)地址和端口号。此 JEP 的目标是支持在各大 Unix 平台和 Windows 上通用的 Unix 域套接字的所有功能。在读/写行为、连接设置、服务器接受传入连接、与选择器中的其他非阻塞可选择通道多路复用以及支持相关套接字选项方面,Unix 域套接字通道的行为将与现有的 TCP/IP 通道相同。
非目标
支持在主流 Unix 平台和 Windows 上不常见的功能并不是目标。这包括特定于 Linux 的功能,例如抽象的与文件系统无关的命名空间。它还包括通常在 Unix 上受支持但在 Windows 上不受支持的功能,例如套接字对。如果需要,并且在缺少的 Windows 功能的情况下,如果 Windows 平台发展到支持它们,则可以重新考虑对这些功能的支持。这一非目标的一个例外是对等凭证的支持,这可以在支持它的平台上实现为 JDK 特定的套接字选项。在此 JEP 完成后,其他套接字选项可能会作为后续工作进行研究,也可能作为 JDK 特定选项。
动机
对于本地的、进程间通信来说,Unix 域套接字比 TCP/IP 回环连接更安全也更高效。
-
Unix 域套接字严格用于同一系统上进程之间的通信。不打算接受远程连接的应用程序可以通过使用 Unix 域套接字来提高安全性。
-
Unix 域套接字还受到操作系统强制执行的、基于文件系统的访问控制的进一步保护。
-
Unix 域套接字的建立时间更快,数据吞吐量比 TCP/IP 回环连接更高。
-
在需要同一系统上的容器之间进行通信的容器环境中,Unix 域套接字可能比 TCP/IP 套接字是更好的解决方案。这可以通过使用位于共享卷中的套接字来实现。
Unix 域套接字长期以来一直是大多数 Unix 平台的一项功能,现在 Windows 10 和 Windows Server 2019 也支持这一功能。
描述
为了支持 Unix 域套接字通道,我们将添加以下 API 元素:
-
一个新的套接字地址类,
java.net.UnixDomainSocketAddress
; -
现有的
java.net.StandardProtocolFamily
枚举中新增一个UNIX
常量值; -
在
SocketChannel
和ServerSocketChannel
上新增指定协议族的open
工厂方法; -
更新了
SocketChannel
和ServerSocketChannel
的规范,明确了与 Unix 域套接字相关的通道行为。
替代方案
一个应用程序可以直接通过 Java 原生接口(JNI)或者 Project Panama 访问 AF_UNIX
地址结构和套接字系统调用。然而,这种类型的套接字对象将与现有的 SocketChannel
API 不兼容,因此无法使用 Selector
API 与其他可选择的通道进行多路复用。
测试
自动单元测试将演练 API 和实现。这些测试将在所有受支持的 Unix 平台上运行,并在多个版本的 Windows 上运行,其中包括一些支持 Unix 域套接字的版本和一些不支持的版本。
风险与假设
现有使用 SocketChannel
和 ServerSocketChannel
类的代码通常假设这些 API 返回的 SocketAddress
实例可以无条件地转换为 InetSocketAddress
。但对于 Unix 域套接字通道,这种转换将会失败。