[−][src]Struct interprocess::os::unix::udsocket::UdStreamListener
A Unix domain byte stream socket server, listening for connections.
All such sockets have the SOCK_STREAM
socket type; in other words, this is the Unix domain version of a TCP server.
Examples
Basic server:
use interprocess::os::unix::udsocket::{UdStream, UdStreamListener}; use std::io::{self, prelude::*}; fn handle_error(result: io::Result<UdStream>) -> Option<UdStream> { match result { Ok(val) => Some(val), Err(error) => { eprintln!("There was an error with an incoming connection: {}", error); None } } } let listener = UdStreamListener::bind("/tmp/example.sock")?; for mut connection in listener.incoming() // Use filter_map to report all errors with connections and skip those connections in the loop, // making the actual server loop part much cleaner than if it contained error handling as well. .filter_map(handle_error) { connection.write_all(b"Hello from server!"); let mut input_string = String::new(); connection.read_to_string(&mut input_string); println!("Client answered: {}", input_string); }
Sending and receiving ancillary data:
use interprocess::{ unnamed_pipe::{pipe, UnnamedPipeReader}, os::unix::udsocket::{UdStreamListener, UdStream, AncillaryData, AncillaryDataBuf}, }; use std::{ io::{self, prelude::*}, fs, iter, borrow::Cow, os::unix::io::{FromRawFd, IntoRawFd}, }; fn handle_error(result: io::Result<UdStream>) -> Option<UdStream> { match result { Ok(val) => Some(val), Err(error) => { eprintln!("There was an error with an incoming connection: {}", error); None } } } let listener = UdStreamListener::bind("/tmp/example.sock")?; // Allocate a sufficient buffer for receiving ancillary data. let mut ancillary_buffer = AncillaryDataBuf::owned_with_capacity( AncillaryData::ENCODED_SIZE_OF_CREDENTIALS + AncillaryData::encoded_size_of_file_descriptors(1), ); // Prepare valid credentials. let credentials = AncillaryData::credentials(); for mut connection in listener.incoming() .filter_map(handle_error) { // Create the file descriptor which we will be sending. let (own_fd, fd_to_send) = pipe()?; // Borrow the file descriptor in a slice right away to send it later. let fds = [fd_to_send.into_raw_fd()]; let fd_ancillary = AncillaryData::FileDescriptors( Cow::Borrowed(&fds), ); connection.send_ancillary( b"File descriptor and credentials from the server!", iter::once(fd_ancillary), ); // The receive buffer size depends on the situation, but since this example // mirrors the second one from UdSocket, 64 is sufficient. let mut recv_buffer = [0; 64]; connection.recv_ancillary( &mut recv_buffer, &mut ancillary_buffer, ); println!("Client answered: {}", String::from_utf8_lossy(&recv_buffer)); // Decode the received ancillary data. let (mut file_descriptors, mut cred) = (None, None); for element in ancillary_buffer.decode() { match element { AncillaryData::FileDescriptors(fds) => file_descriptors = Some(fds), AncillaryData::Credentials {pid, uid, gid} => cred = Some((pid, uid, gid)), } } let mut files = Vec::new(); if let Some(fds) = file_descriptors { // There is a possibility that zero file descriptors were sent — let's account for that. for fd in fds.iter().copied() { // This is normally unsafe, but since we know that the descriptor is not owned somewhere // else in the current process, it's fine to do this: let file = unsafe {fs::File::from_raw_fd(fd)}; files.push(file); } } for mut file in files { file.write(b"Hello foreign file descriptor!"); } if let Some(credentials) = cred { println!("Client\tPID: {}", credentials.0); println!( "\tUID: {}", credentials.1); println!( "\tGID: {}", credentials.2); } }
Implementations
impl UdStreamListener
[src]
pub fn bind<'a>(path: impl ToUdSocketPath<'a>) -> Result<Self>
[src]
Creates a new listener socket at the specified address.
If the socket path exceeds the maximum socket path length (which includes the first 0 byte when using the socket namespace), an error is returned. Errors can also be produced for different reasons, i.e. errors should always be handled regardless of whether the path is known to be short enough or not.
Example
See ToUdSocketPath
.
System calls
socket
bind
pub fn accept(&self) -> Result<UdStream>
[src]
Listens for incoming connections to the socket, blocking until a client is connected.
See incoming
for a convenient way to create a main loop for a server.
Example
use interprocess::os::unix::udsocket::UdStreamListener; let listener = UdStreamListener::bind("/tmp/example.sock")?; loop { match listener.accept() { Ok(connection) => { println!("New client!"); }, Err(error) => { println!("Incoming connection failed: {}", error); }, } }
System calls
accept
pub fn incoming(&self) -> Incoming<'_>ⓘ
[src]
Creates an infinite iterator which calls accept()
with each iteration. Used together with for
loops to conveniently create a main loop for a socket server.
Example
use interprocess::os::unix::udsocket::UdStreamListener; let listener = UdStreamListener::bind("/tmp/example.sock")?; // Thanks to incoming(), you get a simple self-documenting infinite server loop for connection in listener.incoming() .map(|conn| if let Err(error) = conn { eprintln!("Incoming connection failed: {}", error); }) { eprintln!("New client!"); }
Trait Implementations
impl AsRawFd for UdStreamListener
[src]
impl Debug for UdStreamListener
[src]
impl<'a> From<&'a UdStreamListener> for Incoming<'a>
[src]
fn from(listener: &'a UdStreamListener) -> Self
[src]
impl FromRawFd for UdStreamListener
[src]
unsafe fn from_raw_fd(fd: c_int) -> Self
[src]
impl IntoRawFd for UdStreamListener
[src]
fn into_raw_fd(self) -> c_int
[src]
Auto Trait Implementations
impl RefUnwindSafe for UdStreamListener
impl Send for UdStreamListener
impl Sync for UdStreamListener
impl Unpin for UdStreamListener
impl UnwindSafe for UdStreamListener
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,