bigywater.tech
Java · 194

Unix Domain Socket:Java 如何进行本机进程通信

同一台机器上的进程通信,Unix 域套接字比 TCP 回环好在哪?这篇在 JDK 21 上用同样的回显程序实测:延迟、吞吐,以及容易踩的文件残留与路径长度限制(Selector 与 TCP 的基础见前面的篇目)。

4.9 vs 20.1 µs
1 字节来回:Unix 域套接字 vs TCP 回环
1105 vs 2105 MB/s
2 GB 传输吞吐:Unix 域套接字 vs TCP 回环(macOS)
文件不会自动删除
服务端通道关闭后 socket 文件仍在

套接字文件

实测 · 本机执行输出
  服务端绑定到 s.sock;绑定之后这个路径在文件系统里存在吗:true,是普通文件吗:false,是目录吗:false,POSIX 权限:rwxr-xr-x
  客户端发 hello,回显收到:hello;c.getLocalAddress() = ,c.getRemoteAddress() = …/s.sock
  服务端通道关闭之后,socket 文件还在吗:true(不会自动删除)
  文件还在时再次 bind 同一个路径 → BindException: Address already in use
  删除文件之后再 bind:成功
  很长的路径:地址对象创建成功
  路径超过 100 多个字符时:SocketException: Unix domain path too long

与 TCP 对比

实测 · 本机执行输出
  1 字节来回(ping-pong)10 万次的平均往返:Unix 域套接字 4.9 µs,TCP 回环(TCP_NODELAY)20.1 µs
  双向大量传输 2 GB(客户端发、服务端原样回显、客户端同时收):Unix 域套接字 1105 MB/s,TCP 回环 2105 MB/s

分步演示

Unix 域套接字
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12,macOS
    • 没有验证:Linux 上的延迟与吞吐(抽象命名空间的套接字、SO_PEERCRED 凭据读取)、Windows、Selector 与 Unix 域套接字的配合、文件描述符传递(Java 不支持)、socket 文件权限对访问控制的实际效果(只看了权限位);吞吐只测了 2 GB 一次
    京ICP备2026067502号-1京公网安备11010502063487号