Unix Domain Socket(UDS)是一种用于同一台主机上进程间通信(IPC)的机制。与网络套接字不同,UDS不经过网络协议栈,而是通过文件系统进行通信,因此效率更高。(UDS是Unix-like系统(如Linux、macOS)的特性,Windows不支持

主要特点

  • 高效性:由于不涉及网络协议栈,数据传输速度更快;

  • 文件系统路径:UDS使用文件系统路径作为地址,通信双方通过该路径连接;

  • 类型支持:支持流式(SOCK_STREAM)和数据报式(SOCK_DGRAM)通信;

  • 权限控制:可通过文件系统权限控制访问,提升安全性。

使用场景

  • 进程间通信:适用于需要高效通信的本地进程;

  • 安全性要求高的环境:避免网络暴露,减少攻击面;

  • 高性能需求:如数据库、Web服务器等需要快速数据传输的场景。

示例代码

服务器端

import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;

public class UnixDomainSocketServer {
    public static void main(String[] args) throws Exception {
        // 定义UDS文件路径
        Path socketPath = Path.of("/tmp/example.sock");

        // 创建ServerSocketChannel并绑定到UDS路径
        try (ServerSocketChannel serverChannel = ServerSocketChannel.open()) {
            serverChannel.bind(new java.net.UnixDomainSocketAddress(socketPath));

            System.out.println("Server is listening on " + socketPath);

            // 接受客户端连接
            try (SocketChannel clientChannel = serverChannel.accept()) {
                System.out.println("Client connected");

                // 读取客户端发送的数据
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int bytesRead = clientChannel.read(buffer);
                if (bytesRead > 0) {
                    buffer.flip();
                    System.out.println("Received: " + new String(buffer.array(), 0, bytesRead));
                }
            }
        }
    }
}

客户端

import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;

public class UnixDomainSocketClient {
    public static void main(String[] args) throws Exception {
        // 定义UDS文件路径
        Path socketPath = Path.of("/tmp/example.sock");

        // 创建SocketChannel并连接到UDS服务器
        try (SocketChannel clientChannel = SocketChannel.open()) {
            clientChannel.connect(new java.net.UnixDomainSocketAddress(socketPath));

            System.out.println("Connected to server");

            // 发送数据到服务器
            String message = "Hello, Server!";
            ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
            clientChannel.write(buffer);
            System.out.println("Sent: " + message);
        }
    }
}