Skip to content

JEP 380: Unix-Domain Socket Channels | Unix 域套接字通道

摘要

java.nio.channels 包中的 socket channelserver-socket channel API 中添加对 Unix 域(AF_UNIX)套接字的支持。扩展 继承的通道机制 以支持 Unix 域套接字通道和服务器套接字通道。

目标

Unix 域套接字用于同一主机上的进程间通信(IPC)。它们在大多数方面与 TCP/IP 套接字相似,不同之处在于它们通过文件系统路径名而不是互联网协议(IP)地址和端口号进行寻址。本 JEP 的目标是支持在所有主要 Unix 平台和 Windows 上通用的 Unix 域套接字的所有功能。Unix 域套接字通道在读写行为、连接设置、服务器接受传入连接、在选择器中与其他非阻塞可选通道进行多路复用以及支持相关套接字选项方面,将与现有的 TCP/IP 通道表现相同。

非目标

本项目的非目标是不支持那些不是在所有主要 Unix 平台和 Windows 上共有的特性。这包括特定于 Linux 的特性,如与文件系统无关的抽象命名空间。同时,也包括通常在 Unix 上支持但在 Windows 上不受支持的特性,如套接字对(socket pairs)。如果未来需要,并且对于 Windows 平台缺失的特性,如果 Windows 平台发展到支持这些特性,可以重新考虑对这些特性的支持。这一非目标的一个例外是对对等凭证(peer credentials)的支持,这可以在支持它的平台上作为 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 常量值;

  • SocketChannelServerSocketChannel 上添加新的 open 工厂方法,用于指定协议族;

  • 更新 SocketChannelServerSocketChannel 的规范,以指定 Unix 域套接字通道的行为方式。

替代方案

应用程序可以通过 Java 本地接口(JNI)或 Project Panama 直接访问 AF_UNIX 地址结构和套接字系统调用。然而,这种类型的套接字对象将不兼容现有的 SocketChannel API,因此无法使用 Selector API 与其他可选通道进行多路复用。

测试

将通过自动单元测试来检验 API 和实现。这些测试将在所有支持的 Unix 平台和多个版本的 Windows 上运行,包括一些支持 Unix 域套接字和一些不支持的 Windows 版本。

风险和假设

现有使用 SocketChannelServerSocketChannel 类的代码通常假设这些 API 返回的 SocketAddress 实例可以盲目地转换为 InetSocketAddress。但是,在使用 Unix 域套接字通道时,这种转换会失败。