Skip to content

Instantly share code, notes, and snippets.

@gistub
Last active September 13, 2024 08:24
Show Gist options
  • Save gistub/4675704a2b675504b52263791dc89f00 to your computer and use it in GitHub Desktop.
Save gistub/4675704a2b675504b52263791dc89f00 to your computer and use it in GitHub Desktop.
[Rust: Unix Domain Socket] bidirectional socket in #rust

To create a bidirectional unix IPC:

  1. Server creates a sockets and binds it to an address (typically a file). Do NOT use connect as all send/recv operation will be done using connect's address!
  2. Client creates a socket and binds it to its own address. However the socket connects to the address of server.
  3. Server uses recv_from to get data from socket along side with the address of the client that sent the data. This way it can use the address to send a response back to client.

Example in Rust

server.rs

use socket2::SockAddr;
use socket2::{Domain, Socket, Type};

const SRV_SOCKET_FN: &str = "~/tmp/srv.socket";

fn main() {
    let socket_srv = Socket::new(Domain::unix(), Type::dgram(), None).unwrap();
    let addr_srv = SockAddr::unix(SRV_SOCKET_FN).unwrap();
    socket_srv.bind(&addr_srv).unwrap();

    let socket_srv = socket_srv.into_unix_datagram();

    let mut buf = [0; 32];
    // cli_addr will be CLI_SOCKET_FN
    let (_, cli_addr) = socket_srv.recv_from(&mut buf[..]).unwrap();
    // Now we send response back to that specific client
    socket_srv.send_to(buf, cli_addr.as_pathname().unwrap());
}

client.rs

use socket2::SockAddr;
use socket2::{Domain, Socket, Type};

const SRV_SOCKET_FN: &str = "~/tmp/srv.socket";
const CLI_SOCKET_FN: &str = "~/tmp/cli.socket";

fn main() {
    let socket_cli = Socket::new(Domain::unix(), Type::dgram(), None).unwrap();
    let addr_cli = SockAddr::unix(CLI_SOCKET_FN).unwrap();
    let addr_srv = SockAddr::unix(SRV_SOCKET_FN).unwrap();

    // bind to our own address but
    socket_cli.bind(&addr_cli).unwrap();
    // connect to server's address
    socket_cli.connect(&addr_srv).unwrap();

    let socket_cli = socket_cli.into_unix_datagram();

    let buf = [0; 32];
    let n = socket_cli.send(&buf[..]); // will send to SRV_SOCKET_FN

    let mut resp = [0; 32];
    let n = socket_cli.recv(&mut resp[..]); // will receive from SRV_SOCKET_FN
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment