//! Run: //! //! ```bash //! cargo run --example tcp-echo-server //! ``` //! //! Then connect to localhost:7000 //! //! ```bash //! nc localhost 7000 //! ``` //! //! Anything you type will be echoed. extern crate libuv; use libuv::prelude::*; use libuv::{Buf, ReadonlyBuf, TcpBindFlags}; use std::net::Ipv4Addr; const DEFAULT_PORT: u16 = 7000; const DEFAULT_BACKLOG: i32 = 128; fn alloc_buffer(_: Handle, suggested_size: usize) -> Option { Buf::with_capacity(suggested_size).ok() } fn echo_write(mut buf: ReadonlyBuf, status: libuv::Result) { if let Err(e) = status { eprintln!("Write error {}", e); } buf.dealloc(); } fn echo_read(mut client: StreamHandle, nread: libuv::Result, buf: ReadonlyBuf) { match nread { Ok(len) => { if len > 0 { if let Err(e) = client.write(&[buf], move |_, s| echo_write(buf, s)) { eprintln!("Error echoing to socket: {}", e); } } } Err(e) => { if e != libuv::Error::EOF { eprintln!("Read error {}", e); } client.close(()); } } } fn on_new_connection(mut server: StreamHandle, status: libuv::Result) { if let Err(e) = status { eprintln!("New connection error: {}", e); return; } if let Ok(client) = server.get_loop().tcp().as_mut() { match server.accept(&mut client.to_stream()) { Ok(_) => { if let Err(e) = client.read_start(alloc_buffer, echo_read) { eprintln!("Error starting read on client: {}", e); } } Err(e) => { eprintln!("Error accepting connection: {}", e); client.close(()); } } } } fn main() -> Result<(), Box> { let mut r#loop = Loop::default()?; let mut server = r#loop.tcp()?; let addr = (Ipv4Addr::UNSPECIFIED, DEFAULT_PORT).into(); server.bind(&addr, TcpBindFlags::empty())?; server.listen(DEFAULT_BACKLOG, on_new_connection)?; r#loop.run(RunMode::Default)?; Ok(()) }