tcp: add usage examples to TcpListener and TcpStream (#775)

Refs: https://github.com/rust-lang-nursery/wg-net/issues/54
This commit is contained in:
Matt Gathu 2018-11-28 19:05:35 +01:00 committed by Toby Lawrence
parent 4797d79950
commit 1cd0ebfc5e
3 changed files with 616 additions and 1 deletions

View File

@ -27,3 +27,4 @@ futures = "0.1.19"
[dev-dependencies]
env_logger = { version = "0.5", default-features = false }
tokio = { path = ".." }

View File

@ -13,6 +13,36 @@ use tokio_reactor::{Handle, PollEvented};
///
/// This object can be converted into a stream of incoming connections for
/// various forms of processing.
///
/// # Examples
///
/// ```no_run
/// extern crate tokio;
/// extern crate futures;
///
/// use futures::stream::Stream;
/// use std::net::SocketAddr;
/// use tokio::net::{TcpListener, TcpStream};
///
/// fn process_socket(socket: TcpStream) {
/// // ...
/// }
///
/// fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
///
/// // accept connections and process them
/// tokio::run(listener.incoming()
/// .map_err(|e| eprintln!("failed to accept socket; error = {:?}", e))
/// .for_each(|socket| {
/// process_socket(socket);
/// Ok(())
/// })
/// );
/// Ok(())
/// }
/// ```
pub struct TcpListener {
io: PollEvented<mio::net::TcpListener>,
}
@ -22,6 +52,20 @@ impl TcpListener {
///
/// The TCP listener will bind to the provided `addr` address, if available.
/// If the result is `Ok`, the socket has successfully bound.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// use std::net::SocketAddr;
/// use tokio::net::TcpListener;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
/// # Ok(())
/// # }
/// ```
pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
let l = mio::net::TcpListener::bind(addr)?;
Ok(TcpListener::new(l))
@ -54,6 +98,27 @@ impl TcpListener {
/// # Panics
///
/// This function will panic if called from outside of a task context.
///
/// # Examples
///
/// ```no_run
/// # extern crate tokio;
/// # extern crate futures;
/// use std::net::SocketAddr;
/// use tokio::net::TcpListener;
/// use futures::Async;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let mut listener = TcpListener::bind(&addr)?;
/// match listener.poll_accept() {
/// Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
/// Ok(Async::NotReady) => println!("listener not ready to accept!"),
/// Err(e) => eprintln!("got an error: {}", e),
/// }
/// # Ok(())
/// # }
/// ```
pub fn poll_accept(&mut self) -> Poll<(TcpStream, SocketAddr), io::Error> {
let (io, addr) = try_ready!(self.poll_accept_std());
@ -91,6 +156,27 @@ impl TcpListener {
/// # Panics
///
/// This function will panic if called from outside of a task context.
///
/// # Examples
///
/// ```no_run
/// # extern crate tokio;
/// # extern crate futures;
/// use std::net::SocketAddr;
/// use tokio::net::TcpListener;
/// use futures::Async;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let mut listener = TcpListener::bind(&addr)?;
/// match listener.poll_accept_std() {
/// Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
/// Ok(Async::NotReady) => println!("listener not ready to accept!"),
/// Err(e) => eprintln!("got an error: {}", e),
/// }
/// # Ok(())
/// # }
/// ```
pub fn poll_accept_std(&mut self) -> Poll<(net::TcpStream, SocketAddr), io::Error> {
try_ready!(self.io.poll_read_ready(mio::Ready::readable()));
@ -121,7 +207,7 @@ impl TcpListener {
///
/// Finally, the `handle` argument is the event loop that this listener will
/// be bound to.
/// Use `Handle::default()` to lazily bind to an event loop, just like `bind` does.
/// Use [`Handle::default()`] to lazily bind to an event loop, just like `bind` does.
///
/// The platform specific behavior of this function looks like:
///
@ -132,6 +218,23 @@ impl TcpListener {
/// will only be for the same IP version as `addr` specified. That is, if
/// `addr` is an IPv4 address then all sockets accepted will be IPv4 as
/// well (same for IPv6).
///
/// [`Handle::default()`]: ../reactor/struct.Handle.html
/// # Examples
///
/// ```no_run
/// # extern crate tokio;
/// # extern crate tokio_reactor;
/// use tokio::net::TcpListener;
/// use std::net::TcpListener as StdTcpListener;
/// use tokio::reactor::Handle;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let std_listener = StdTcpListener::bind("127.0.0.1:8080")?;
/// let listener = TcpListener::from_std(std_listener, &Handle::default())?;
/// # Ok(())
/// # }
/// ```
pub fn from_std(listener: net::TcpListener, handle: &Handle)
-> io::Result<TcpListener>
{
@ -149,6 +252,22 @@ impl TcpListener {
///
/// This can be useful, for example, when binding to port 0 to figure out
/// which port was actually bound.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// use tokio::net::TcpListener;
/// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
/// assert_eq!(listener.local_addr()?,
/// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
/// # Ok(())
/// # }
/// ```
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.io.get_ref().local_addr()
}
@ -168,6 +287,29 @@ impl TcpListener {
///
/// If aiming for production, decision what to do about them must be made. The
/// [`tk-listen`](https://crates.io/crates/tk-listen) crate might be of some help.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpListener;
/// use futures::stream::Stream;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
///
/// listener.incoming()
/// .map_err(|e| eprintln!("failed to accept stream; error = {:?}", e))
/// .for_each(|_socket| {
/// println!("new socket!");
/// Ok(())
/// });
/// # Ok(())
/// # }
/// ```
pub fn incoming(self) -> Incoming {
Incoming::new(self)
}
@ -177,6 +319,22 @@ impl TcpListener {
/// For more information about this option, see [`set_ttl`].
///
/// [`set_ttl`]: #method.set_ttl
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// use tokio::net::TcpListener;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
/// listener.set_ttl(100).expect("could not set TTL");
/// assert_eq!(listener.ttl()?, 100);
/// # Ok(())
/// # }
/// ```
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
}
@ -185,6 +343,21 @@ impl TcpListener {
///
/// This value sets the time-to-live field that is used in every packet sent
/// from this socket.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// use tokio::net::TcpListener;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let listener = TcpListener::bind(&addr)?;
/// listener.set_ttl(100).expect("could not set TTL");
/// # Ok(())
/// # }
/// ```
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
self.io.get_ref().set_ttl(ttl)
}

View File

@ -19,6 +19,27 @@ use tokio_reactor::{Handle, PollEvented};
/// [`connect`]: struct.TcpStream.html#method.connect
/// [accepting]: struct.TcpListener.html#method.accept
/// [listener]: struct.TcpListener.html
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use futures::Future;
/// use tokio::io::AsyncWrite;
/// use tokio::net::TcpStream;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:34254".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|mut stream| {
/// // Attempt to write bytes asynchronously to the stream
/// stream.poll_write(&[1]);
/// });
/// # Ok(())
/// # }
/// ```
pub struct TcpStream {
io: PollEvented<mio::net::TcpStream>,
}
@ -46,6 +67,24 @@ impl TcpStream {
/// the `addr` provided. The returned future will be resolved once the
/// stream has successfully connected, or it will return an error if one
/// occurs.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use futures::Future;
/// use tokio::net::TcpStream;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:34254".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr)
/// .map(|stream|
/// println!("successfully connected to {}", stream.local_addr().unwrap()));
/// # Ok(())
/// # }
/// ```
pub fn connect(addr: &SocketAddr) -> ConnectFuture {
use self::ConnectFutureState::*;
@ -67,6 +106,22 @@ impl TcpStream {
/// This function will convert a TCP stream created by the standard library
/// to a TCP stream ready to be used with the provided event loop handle.
/// Use `Handle::default()` to lazily bind to an event loop, just like `connect` does.
///
/// # Examples
///
/// ```no_run
/// # extern crate tokio;
/// # extern crate tokio_reactor;
/// use tokio::net::TcpStream;
/// use std::net::TcpStream as StdTcpStream;
/// use tokio_reactor::Handle;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let std_stream = StdTcpStream::connect("127.0.0.1:34254")?;
/// let stream = TcpStream::from_std(std_stream, &Handle::default())?;
/// # Ok(())
/// # }
/// ```
pub fn from_std(stream: net::TcpStream, handle: &Handle)
-> io::Result<TcpStream>
{
@ -131,6 +186,32 @@ impl TcpStream {
///
/// * `ready` includes writable.
/// * called from outside of a task context.
///
/// # Examples
///
/// ```
/// # extern crate mio;
/// # extern crate tokio;
/// # extern crate futures;
/// use mio::Ready;
/// use futures::Async;
/// use futures::Future;
/// use tokio::net::TcpStream;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:34254".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// match stream.poll_read_ready(Ready::readable()) {
/// Ok(Async::Ready(_)) => println!("read ready"),
/// Ok(Async::NotReady) => println!("not read ready"),
/// Err(e) => eprintln!("got error: {}", e),
/// }
/// });
/// # Ok(())
/// # }
/// ```
pub fn poll_read_ready(&self, mask: mio::Ready) -> Poll<mio::Ready, io::Error> {
self.io.poll_read_ready(mask)
}
@ -149,16 +230,79 @@ impl TcpStream {
/// # Panics
///
/// This function panics if called from outside of a task context.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use futures::Async;
/// use futures::Future;
/// use tokio::net::TcpStream;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:34254".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// match stream.poll_write_ready() {
/// Ok(Async::Ready(_)) => println!("write ready"),
/// Ok(Async::NotReady) => println!("not write ready"),
/// Err(e) => eprintln!("got error: {}", e),
/// }
/// });
/// # Ok(())
/// # }
/// ```
pub fn poll_write_ready(&self) -> Poll<mio::Ready, io::Error> {
self.io.poll_write_ready()
}
/// Returns the local address that this stream is bound to.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// assert_eq!(stream.local_addr().unwrap(),
/// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
/// });
/// # Ok(())
/// # }
/// ```
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.io.get_ref().local_addr()
}
/// Returns the remote address that this stream is connected to.
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// assert_eq!(stream.peer_addr().unwrap(),
/// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
/// });
/// # Ok(())
/// # }
/// ```
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
self.io.get_ref().peer_addr()
}
@ -190,6 +334,31 @@ impl TcpStream {
/// # Panics
///
/// This function will panic if called from outside of a task context.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Async;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|mut stream| {
/// let mut buf = [0; 10];
/// match stream.poll_peek(&mut buf) {
/// Ok(Async::Ready(len)) => println!("read {} bytes", len),
/// Ok(Async::NotReady) => println!("no data available"),
/// Err(e) => eprintln!("got error: {}", e),
/// }
/// });
/// # Ok(())
/// # }
/// ```
pub fn poll_peek(&mut self, buf: &mut [u8]) -> Poll<usize, io::Error> {
try_ready!(self.io.poll_read_ready(mio::Ready::readable()));
@ -208,6 +377,25 @@ impl TcpStream {
/// This function will cause all pending and future I/O on the specified
/// portions to return immediately with an appropriate value (see the
/// documentation of `Shutdown`).
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::{Shutdown, SocketAddr};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.shutdown(Shutdown::Both)
/// });
/// # Ok(())
/// # }
/// ```
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.io.get_ref().shutdown(how)
}
@ -217,6 +405,26 @@ impl TcpStream {
/// For more information about this option, see [`set_nodelay`].
///
/// [`set_nodelay`]: #method.set_nodelay
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_nodelay(true).expect("set_nodelay call failed");;
/// assert_eq!(stream.nodelay().unwrap_or(false), true);
/// });
/// # Ok(())
/// # }
/// ```
pub fn nodelay(&self) -> io::Result<bool> {
self.io.get_ref().nodelay()
}
@ -228,6 +436,25 @@ impl TcpStream {
/// small amount of data. When not set, data is buffered until there is a
/// sufficient amount to send out, thereby avoiding the frequent sending of
/// small packets.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_nodelay(true).expect("set_nodelay call failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
self.io.get_ref().set_nodelay(nodelay)
}
@ -237,6 +464,26 @@ impl TcpStream {
/// For more information about this option, see [`set_recv_buffer_size`].
///
/// [`set_recv_buffer_size`]: #tymethod.set_recv_buffer_size
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_recv_buffer_size(100).expect("set_recv_buffer_size failed");
/// assert_eq!(stream.recv_buffer_size().unwrap_or(0), 100);
/// });
/// # Ok(())
/// # }
/// ```
pub fn recv_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().recv_buffer_size()
}
@ -245,6 +492,25 @@ impl TcpStream {
///
/// Changes the size of the operating system's receive buffer associated
/// with the socket.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_recv_buffer_size(100).expect("set_recv_buffer_size failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
self.io.get_ref().set_recv_buffer_size(size)
}
@ -254,6 +520,26 @@ impl TcpStream {
/// For more information about this option, see [`set_send_buffer`].
///
/// [`set_send_buffer`]: #tymethod.set_send_buffer
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_send_buffer_size(100).expect("set_send_buffer_size failed");
/// assert_eq!(stream.send_buffer_size().unwrap_or(0), 100);
/// });
/// # Ok(())
/// # }
/// ```
pub fn send_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().send_buffer_size()
}
@ -262,6 +548,25 @@ impl TcpStream {
///
/// Changes the size of the operating system's send buffer associated with
/// the socket.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_send_buffer_size(100).expect("set_send_buffer_size failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
self.io.get_ref().set_send_buffer_size(size)
}
@ -272,6 +577,26 @@ impl TcpStream {
/// For more information about this option, see [`set_keepalive`].
///
/// [`set_keepalive`]: #tymethod.set_keepalive
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_keepalive(None).expect("set_keepalive failed");
/// assert_eq!(stream.keepalive().unwrap(), None);
/// });
/// # Ok(())
/// # }
/// ```
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
self.io.get_ref().keepalive()
}
@ -288,6 +613,25 @@ impl TcpStream {
///
/// Some platforms specify this value in seconds, so sub-second
/// specifications may be omitted.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_keepalive(None).expect("set_keepalive failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
self.io.get_ref().set_keepalive(keepalive)
}
@ -297,6 +641,26 @@ impl TcpStream {
/// For more information about this option, see [`set_ttl`].
///
/// [`set_ttl`]: #tymethod.set_ttl
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_ttl(100).expect("set_ttl failed");
/// assert_eq!(stream.ttl().unwrap_or(0), 100);
/// });
/// # Ok(())
/// # }
/// ```
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
}
@ -305,6 +669,25 @@ impl TcpStream {
///
/// This value sets the time-to-live field that is used in every packet sent
/// from this socket.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_ttl(100).expect("set_ttl failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
self.io.get_ref().set_ttl(ttl)
}
@ -315,6 +698,26 @@ impl TcpStream {
/// For more information about this option, see [`set_linger`].
///
/// [`set_linger`]: #tymethod.set_linger
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_linger(None).expect("set_linger failed");
/// assert_eq!(stream.linger().unwrap(), None);
/// });
/// # Ok(())
/// # }
/// ```
pub fn linger(&self) -> io::Result<Option<Duration>> {
self.io.get_ref().linger()
}
@ -330,6 +733,25 @@ impl TcpStream {
/// If `SO_LINGER` is not specified, and the stream is closed, the system
/// handles the call in a way that allows the process to continue as quickly
/// as possible.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// stream.set_linger(None).expect("set_linger failed");
/// });
/// # Ok(())
/// # }
/// ```
pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
self.io.get_ref().set_linger(dur)
}
@ -340,6 +762,25 @@ impl TcpStream {
/// object references. Both handles will read and write the same stream of
/// data, and options set on one stream will be propagated to the other
/// stream.
///
/// # Examples
///
/// ```
/// # extern crate tokio;
/// # extern crate futures;
/// use tokio::net::TcpStream;
/// use futures::Future;
/// use std::net::SocketAddr;
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
/// let stream = TcpStream::connect(&addr);
/// stream.map(|stream| {
/// let clone = stream.try_clone().unwrap();
/// });
/// # Ok(())
/// # }
/// ```
pub fn try_clone(&self) -> io::Result<TcpStream> {
let io = self.io.get_ref().try_clone()?;
Ok(TcpStream::new(io))