tokio_tcp/
listener.rs

1use super::Incoming;
2use super::TcpStream;
3
4use std::fmt;
5use std::io;
6use std::net::{self, SocketAddr};
7
8use futures::{Async, Poll};
9use mio;
10use tokio_reactor::{Handle, PollEvented};
11
12/// An I/O object representing a TCP socket listening for incoming connections.
13///
14/// This object can be converted into a stream of incoming connections for
15/// various forms of processing.
16///
17/// # Examples
18///
19/// ```no_run
20/// extern crate tokio;
21/// extern crate futures;
22///
23/// use futures::stream::Stream;
24/// use std::net::SocketAddr;
25/// use tokio::net::{TcpListener, TcpStream};
26///
27/// fn process_socket(socket: TcpStream) {
28///     // ...
29/// }
30///
31/// fn main() -> Result<(), Box<std::error::Error>> {
32///     let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
33///     let listener = TcpListener::bind(&addr)?;
34///
35///     // accept connections and process them
36///     tokio::run(listener.incoming()
37///         .map_err(|e| eprintln!("failed to accept socket; error = {:?}", e))
38///         .for_each(|socket| {
39///             process_socket(socket);
40///             Ok(())
41///         })
42///     );
43///     Ok(())
44/// }
45/// ```
46pub struct TcpListener {
47    io: PollEvented<mio::net::TcpListener>,
48}
49
50impl TcpListener {
51    /// Create a new TCP listener associated with this event loop.
52    ///
53    /// The TCP listener will bind to the provided `addr` address, if available.
54    /// If the result is `Ok`, the socket has successfully bound.
55    ///
56    /// # Examples
57    ///
58    /// ```
59    /// # extern crate tokio;
60    /// use std::net::SocketAddr;
61    /// use tokio::net::TcpListener;
62    ///
63    /// # fn main() -> Result<(), Box<std::error::Error>> {
64    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
65    /// let listener = TcpListener::bind(&addr)?;
66    /// # Ok(())
67    /// # }
68    /// ```
69    pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
70        let l = mio::net::TcpListener::bind(addr)?;
71        Ok(TcpListener::new(l))
72    }
73
74    #[deprecated(since = "0.1.2", note = "use poll_accept instead")]
75    #[doc(hidden)]
76    pub fn accept(&mut self) -> io::Result<(TcpStream, SocketAddr)> {
77        match self.poll_accept()? {
78            Async::Ready(ret) => Ok(ret),
79            Async::NotReady => Err(io::ErrorKind::WouldBlock.into()),
80        }
81    }
82
83    /// Attempt to accept a connection and create a new connected `TcpStream` if
84    /// successful.
85    ///
86    /// Note that typically for simple usage it's easier to treat incoming
87    /// connections as a `Stream` of `TcpStream`s with the `incoming` method
88    /// below.
89    ///
90    /// # Return
91    ///
92    /// On success, returns `Ok(Async::Ready((socket, addr)))`.
93    ///
94    /// If the listener is not ready to accept, the method returns
95    /// `Ok(Async::NotReady)` and arranges for the current task to receive a
96    /// notification when the listener becomes ready to accept.
97    ///
98    /// # Panics
99    ///
100    /// This function will panic if called from outside of a task context.
101    ///
102    /// # Examples
103    ///
104    /// ```no_run
105    /// # extern crate tokio;
106    /// # extern crate futures;
107    /// use std::net::SocketAddr;
108    /// use tokio::net::TcpListener;
109    /// use futures::Async;
110    ///
111    /// # fn main() -> Result<(), Box<std::error::Error>> {
112    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
113    /// let mut listener = TcpListener::bind(&addr)?;
114    /// match listener.poll_accept() {
115    ///     Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
116    ///     Ok(Async::NotReady) => println!("listener not ready to accept!"),
117    ///     Err(e) => eprintln!("got an error: {}", e),
118    /// }
119    /// # Ok(())
120    /// # }
121    /// ```
122    pub fn poll_accept(&mut self) -> Poll<(TcpStream, SocketAddr), io::Error> {
123        let (io, addr) = try_ready!(self.poll_accept_std());
124
125        let io = mio::net::TcpStream::from_stream(io)?;
126        let io = TcpStream::new(io);
127
128        Ok((io, addr).into())
129    }
130
131    #[deprecated(since = "0.1.2", note = "use poll_accept_std instead")]
132    #[doc(hidden)]
133    pub fn accept_std(&mut self) -> io::Result<(net::TcpStream, SocketAddr)> {
134        match self.poll_accept_std()? {
135            Async::Ready(ret) => Ok(ret),
136            Async::NotReady => Err(io::ErrorKind::WouldBlock.into()),
137        }
138    }
139
140    /// Attempt to accept a connection and create a new connected `TcpStream` if
141    /// successful.
142    ///
143    /// This function is the same as `accept` above except that it returns a
144    /// `std::net::TcpStream` instead of a `tokio::net::TcpStream`. This in turn
145    /// can then allow for the TCP stream to be associated with a different
146    /// reactor than the one this `TcpListener` is associated with.
147    ///
148    /// # Return
149    ///
150    /// On success, returns `Ok(Async::Ready((socket, addr)))`.
151    ///
152    /// If the listener is not ready to accept, the method returns
153    /// `Ok(Async::NotReady)` and arranges for the current task to receive a
154    /// notification when the listener becomes ready to accept.
155    ///
156    /// # Panics
157    ///
158    /// This function will panic if called from outside of a task context.
159    ///
160    /// # Examples
161    ///
162    /// ```no_run
163    /// # extern crate tokio;
164    /// # extern crate futures;
165    /// use std::net::SocketAddr;
166    /// use tokio::net::TcpListener;
167    /// use futures::Async;
168    ///
169    /// # fn main() -> Result<(), Box<std::error::Error>> {
170    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
171    /// let mut listener = TcpListener::bind(&addr)?;
172    /// match listener.poll_accept_std() {
173    ///     Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
174    ///     Ok(Async::NotReady) => println!("listener not ready to accept!"),
175    ///     Err(e) => eprintln!("got an error: {}", e),
176    /// }
177    /// # Ok(())
178    /// # }
179    /// ```
180    pub fn poll_accept_std(&mut self) -> Poll<(net::TcpStream, SocketAddr), io::Error> {
181        try_ready!(self.io.poll_read_ready(mio::Ready::readable()));
182
183        match self.io.get_ref().accept_std() {
184            Ok(pair) => Ok(pair.into()),
185            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
186                self.io.clear_read_ready(mio::Ready::readable())?;
187                Ok(Async::NotReady)
188            }
189            Err(e) => Err(e),
190        }
191    }
192
193    /// Create a new TCP listener from the standard library's TCP listener.
194    ///
195    /// This method can be used when the `Handle::tcp_listen` method isn't
196    /// sufficient because perhaps some more configuration is needed in terms of
197    /// before the calls to `bind` and `listen`.
198    ///
199    /// This API is typically paired with the `net2` crate and the `TcpBuilder`
200    /// type to build up and customize a listener before it's shipped off to the
201    /// backing event loop. This allows configuration of options like
202    /// `SO_REUSEPORT`, binding to multiple addresses, etc.
203    ///
204    /// The `addr` argument here is one of the addresses that `listener` is
205    /// bound to and the listener will only be guaranteed to accept connections
206    /// of the same address type currently.
207    ///
208    /// Finally, the `handle` argument is the event loop that this listener will
209    /// be bound to.
210    /// Use [`Handle::default()`] to lazily bind to an event loop, just like `bind` does.
211    ///
212    /// The platform specific behavior of this function looks like:
213    ///
214    /// * On Unix, the socket is placed into nonblocking mode and connections
215    ///   can be accepted as normal
216    ///
217    /// * On Windows, the address is stored internally and all future accepts
218    ///   will only be for the same IP version as `addr` specified. That is, if
219    ///   `addr` is an IPv4 address then all sockets accepted will be IPv4 as
220    ///   well (same for IPv6).
221    ///
222    /// [`Handle::default()`]: ../reactor/struct.Handle.html
223    /// # Examples
224    ///
225    /// ```no_run
226    /// # extern crate tokio;
227    /// # extern crate tokio_reactor;
228    /// use tokio::net::TcpListener;
229    /// use std::net::TcpListener as StdTcpListener;
230    /// use tokio::reactor::Handle;
231    ///
232    /// # fn main() -> Result<(), Box<std::error::Error>> {
233    /// let std_listener = StdTcpListener::bind("127.0.0.1:0")?;
234    /// let listener = TcpListener::from_std(std_listener, &Handle::default())?;
235    /// # Ok(())
236    /// # }
237    /// ```
238    pub fn from_std(listener: net::TcpListener, handle: &Handle) -> io::Result<TcpListener> {
239        let io = mio::net::TcpListener::from_std(listener)?;
240        let io = PollEvented::new_with_handle(io, handle)?;
241        Ok(TcpListener { io })
242    }
243
244    fn new(listener: mio::net::TcpListener) -> TcpListener {
245        let io = PollEvented::new(listener);
246        TcpListener { io }
247    }
248
249    /// Returns the local address that this listener is bound to.
250    ///
251    /// This can be useful, for example, when binding to port 0 to figure out
252    /// which port was actually bound.
253    ///
254    /// # Examples
255    ///
256    /// ```
257    /// # extern crate tokio;
258    /// use tokio::net::TcpListener;
259    /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
260    ///
261    /// # fn main() -> Result<(), Box<std::error::Error>> {
262    /// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
263    /// let listener = TcpListener::bind(&addr)?;
264    /// assert_eq!(listener.local_addr()?,
265    ///            SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
266    /// # Ok(())
267    /// # }
268    /// ```
269    pub fn local_addr(&self) -> io::Result<SocketAddr> {
270        self.io.get_ref().local_addr()
271    }
272
273    /// Consumes this listener, returning a stream of the sockets this listener
274    /// accepts.
275    ///
276    /// This method returns an implementation of the `Stream` trait which
277    /// resolves to the sockets the are accepted on this listener.
278    ///
279    /// # Errors
280    ///
281    /// Note that accepting a connection can lead to various errors and not all of them are
282    /// necessarily fatal ‒ for example having too many open file descriptors or the other side
283    /// closing the connection while it waits in an accept queue. These would terminate the stream
284    /// if not handled in any way.
285    ///
286    /// If aiming for production, decision what to do about them must be made. The
287    /// [`tk-listen`](https://crates.io/crates/tk-listen) crate might be of some help.
288    ///
289    /// # Examples
290    ///
291    /// ```
292    /// # extern crate tokio;
293    /// # extern crate futures;
294    /// use tokio::net::TcpListener;
295    /// use futures::stream::Stream;
296    /// use std::net::SocketAddr;
297    ///
298    /// # fn main() -> Result<(), Box<std::error::Error>> {
299    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
300    /// let listener = TcpListener::bind(&addr)?;
301    ///
302    /// listener.incoming()
303    ///     .map_err(|e| eprintln!("failed to accept stream; error = {:?}", e))
304    ///     .for_each(|_socket| {
305    ///         println!("new socket!");
306    ///         Ok(())
307    ///     });
308    /// # Ok(())
309    /// # }
310    /// ```
311    pub fn incoming(self) -> Incoming {
312        Incoming::new(self)
313    }
314
315    /// Gets the value of the `IP_TTL` option for this socket.
316    ///
317    /// For more information about this option, see [`set_ttl`].
318    ///
319    /// [`set_ttl`]: #method.set_ttl
320    ///
321    /// # Examples
322    ///
323    /// ```
324    /// # extern crate tokio;
325    /// use tokio::net::TcpListener;
326    /// use std::net::SocketAddr;
327    ///
328    /// # fn main() -> Result<(), Box<std::error::Error>> {
329    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
330    /// let listener = TcpListener::bind(&addr)?;
331    /// listener.set_ttl(100).expect("could not set TTL");
332    /// assert_eq!(listener.ttl()?, 100);
333    /// # Ok(())
334    /// # }
335    /// ```
336    pub fn ttl(&self) -> io::Result<u32> {
337        self.io.get_ref().ttl()
338    }
339
340    /// Sets the value for the `IP_TTL` option on this socket.
341    ///
342    /// This value sets the time-to-live field that is used in every packet sent
343    /// from this socket.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// # extern crate tokio;
349    /// use tokio::net::TcpListener;
350    /// use std::net::SocketAddr;
351    ///
352    /// # fn main() -> Result<(), Box<std::error::Error>> {
353    /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
354    /// let listener = TcpListener::bind(&addr)?;
355    /// listener.set_ttl(100).expect("could not set TTL");
356    /// # Ok(())
357    /// # }
358    /// ```
359    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
360        self.io.get_ref().set_ttl(ttl)
361    }
362}
363
364impl fmt::Debug for TcpListener {
365    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
366        self.io.get_ref().fmt(f)
367    }
368}
369
370#[cfg(unix)]
371mod sys {
372    use super::TcpListener;
373    use std::os::unix::prelude::*;
374
375    impl AsRawFd for TcpListener {
376        fn as_raw_fd(&self) -> RawFd {
377            self.io.get_ref().as_raw_fd()
378        }
379    }
380}
381
382#[cfg(windows)]
383mod sys {
384    // TODO: let's land these upstream with mio and then we can add them here.
385    //
386    // use std::os::windows::prelude::*;
387    // use super::{TcpListener;
388    //
389    // impl AsRawHandle for TcpListener {
390    //     fn as_raw_handle(&self) -> RawHandle {
391    //         self.listener.io().as_raw_handle()
392    //     }
393    // }
394}