Los Unix-Domain socket channels, agregados en Java 16 (JEP 380), son una característica de Java diseñada para mejorar la comunicación entre procesadores en el mismo host, sobre el uso de TCP/IP.
Comunicación desde el mismo host
La comunicación sincrónica entre dos procesos discretos que se encuentran en el mismo host es una necesidad algo común. Para Java, esto se ha realizado principalmente a través de conexiones TCP/IP. Las conexiones TCP/IP tienen una sobrecarga relativamente alta en la configuración y también un rendimiento limitado. Para una aplicación que solo se comunica con un proceso local, esto también abre una vulnerabilidad de seguridad, ya que necesitarán aceptar conexiones remotas.
Los Unix-Domain Socket Channels (Sockets Unix), agregados en Java 16, hacen uso de la familia de sockets AF_UNIX (AF_LOCAL). Los sockets Unix están estrictamente limitados a la comunicación dentro del host, pero ofrecen:
- Configuración más rápida y mayor rendimiento que las conexiones de bucle invertido TCP / IP
- Permitir controles del sistema de archivos de controles forzados por el SO
- Puede trabajar con contenedores a través de volúmenes compartidos.
Además, a pesar de su nombre, Unix Sockets incluso funciona en Windows 10 y Windows Server 2019.
Configurando la comunicación
La configuración adecuada de un socket Unix requiere la configuración de un “servidor” y un “cliente” como en los ejemplos siguientes.
Server
var direccion = UnixDomainSocketAddress.of("/mnt/server");
try (var servidor = ServerSocketChannel.open(UNIX)) {
servidor.bind(direccion);
try (var cliente = servidor.accept()) {
ByteBuffer buf = ByteBuffer.allocate(64);
cliente.read(buf);
buf.flip();
System.out.printf("Leimos %d bytes\n", buf.remaining());
}
} finally {
Files.deleteIfExists(direccion.getPath());
}
En el ejemplo anterior, /mnt/server es la ruta del socket.
A continuación, se debe abrir el canal: var serverChannel = ServerSocketChannel.open(UNIX)
A continuación, se debe indicar al servidor que escuche la comunicación procedente del canal: var clientChannel = serverChannel.accept()
Para extraer los datos enviados en los datos, use read(): clientChannel.read(buf)
Cliente
var direccion = UnixDomainSocketAddress.of("/mnt/server");
try (var cliente = SocketChannel.open(direccion)) {
ByteBuffer buf = ByteBuffer.wrap("Hola socket".getBytes());
cliente.write(buf);
}
El canal a la ruta definida /mnt/server debe estar abierto: var clientChannel = SocketChannel.open(dirección)
Para enviar datos a través del canal, use write(): clientChannel.write(buf);