通过例子学习Rust

43 套接字

Inter-Process Communication (IPC) for client-server applications can be accomplished using UNIX sockets.

Both client and server need to use the same path for the socket.

// common.rs
pub static SOCKET_PATH: &'static str = "loopback-socket";

The client program:

// client.rs
use common::SOCKET_PATH;
use std::io::net::pipe::UnixStream;
use std::os;

mod common;

fn main() {
    // `args` returns the arguments passed to the program
    let args = os::args();
    let socket = Path::new(SOCKET_PATH);

    // First argument is the message to be sent
    let message = match args.as_slice() {
        [_, ref message] => message.as_slice(),
        _ => panic!("wrong number of arguments"),
    };

    // Connect to socket
    let mut stream = match UnixStream::connect(&socket) {
        Err(_) => panic!("server is not running"),
        Ok(stream) => stream,
    };

    // Send message
    match stream.write_str(message) {
        Err(_) => panic!("couldn't send message"),
        Ok(_) => {}
    }
}

The server program:

// server.rs
use common::SOCKET_PATH;
use std::io::fs;
use std::io::fs::PathExtensions;
use std::io::net::pipe::UnixListener;
use std::io::{Acceptor,Listener};

mod common;

fn main() {
    let socket = Path::new(SOCKET_PATH);

    // Delete old socket if necessary
    if socket.exists() {
        fs::unlink(&socket).unwrap();
    }

    // Bind to socket
    let stream = match UnixListener::bind(&socket) {
        Err(_) => panic!("failed to bind socket"),
        Ok(stream) => stream,
    };

    println!("Server started, waiting for clients");

    // Iterate over clients, blocks if no client available
    for mut client in stream.listen().incoming() {
        println!("Client said: {}", client.read_to_string().unwrap());
    }
}

Let's test the programs

$ rustc client.rs; rustc server.rs

# Terminal 1
$ ./server
Server started, waiting for clients

# Terminal 2
$ ./client hello

# Terminal 1
Server started, waiting for clients
Client said: hello