tokio/net/tcp/listener.rs
1use crate::io::{Interest, PollEvented};
2use crate::net::tcp::TcpStream;
3
4cfg_not_wasi! {
5 use crate::net::{to_socket_addrs, ToSocketAddrs};
6}
7
8use std::fmt;
9use std::io;
10use std::net::{self, SocketAddr};
11use std::task::{ready, Context, Poll};
12
13cfg_net! {
14 /// A TCP socket server, listening for connections.
15 ///
16 /// You can accept a new connection by using the [`accept`](`TcpListener::accept`)
17 /// method.
18 ///
19 /// A `TcpListener` can be turned into a `Stream` with [`TcpListenerStream`].
20 ///
21 /// [`TcpListenerStream`]: https://docs.rs/tokio-stream/0.1/tokio_stream/wrappers/struct.TcpListenerStream.html
22 ///
23 /// # Errors
24 ///
25 /// Note that accepting a connection can lead to various errors and not all
26 /// of them are necessarily fatal ‒ for example having too many open file
27 /// descriptors or the other side closing the connection while it waits in
28 /// an accept queue. These would terminate the stream if not handled in any
29 /// way.
30 ///
31 /// # Examples
32 ///
33 /// Using `accept`:
34 /// ```no_run
35 /// use tokio::net::TcpListener;
36 ///
37 /// use std::io;
38 ///
39 /// async fn process_socket<T>(socket: T) {
40 /// # drop(socket);
41 /// // do work with socket here
42 /// }
43 ///
44 /// #[tokio::main]
45 /// async fn main() -> io::Result<()> {
46 /// let listener = TcpListener::bind("127.0.0.1:8080").await?;
47 ///
48 /// loop {
49 /// let (socket, _) = listener.accept().await?;
50 /// process_socket(socket).await;
51 /// }
52 /// }
53 /// ```
54 pub struct TcpListener {
55 io: PollEvented<mio::net::TcpListener>,
56 }
57}
58
59impl TcpListener {
60 cfg_not_wasi! {
61 /// Creates a new `TcpListener`, which will be bound to the specified address.
62 ///
63 /// The returned listener is ready for accepting connections.
64 ///
65 /// Binding with a port number of 0 will request that the OS assigns a port
66 /// to this listener. The port allocated can be queried via the `local_addr`
67 /// method.
68 ///
69 /// The address type can be any implementor of the [`ToSocketAddrs`] trait.
70 /// If `addr` yields multiple addresses, bind will be attempted with each of
71 /// the addresses until one succeeds and returns the listener. If none of
72 /// the addresses succeed in creating a listener, the error returned from
73 /// the last attempt (the last address) is returned.
74 ///
75 /// This function sets the `SO_REUSEADDR` option on the socket.
76 ///
77 /// To configure the socket before binding, you can use the [`TcpSocket`]
78 /// type.
79 ///
80 /// [`ToSocketAddrs`]: trait@crate::net::ToSocketAddrs
81 /// [`TcpSocket`]: struct@crate::net::TcpSocket
82 ///
83 /// # Examples
84 ///
85 /// ```no_run
86 /// # if cfg!(miri) { return } // No `socket` in miri.
87 /// use tokio::net::TcpListener;
88 ///
89 /// use std::io;
90 ///
91 /// #[tokio::main]
92 /// async fn main() -> io::Result<()> {
93 /// let listener = TcpListener::bind("127.0.0.1:2345").await?;
94 ///
95 /// // use the listener
96 ///
97 /// # let _ = listener;
98 /// Ok(())
99 /// }
100 /// ```
101 pub async fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
102 let addrs = to_socket_addrs(addr).await?;
103
104 let mut last_err = None;
105
106 for addr in addrs {
107 match TcpListener::bind_addr(addr) {
108 Ok(listener) => return Ok(listener),
109 Err(e) => last_err = Some(e),
110 }
111 }
112
113 Err(last_err.unwrap_or_else(|| {
114 io::Error::new(
115 io::ErrorKind::InvalidInput,
116 "could not resolve to any address",
117 )
118 }))
119 }
120
121 fn bind_addr(addr: SocketAddr) -> io::Result<TcpListener> {
122 let listener = mio::net::TcpListener::bind(addr)?;
123 TcpListener::new(listener)
124 }
125 }
126
127 /// Accepts a new incoming connection from this listener.
128 ///
129 /// This function will yield once a new TCP connection is established. When
130 /// established, the corresponding [`TcpStream`] and the remote peer's
131 /// address will be returned.
132 ///
133 /// # Cancel safety
134 ///
135 /// This method is cancel safe. If the method is used as the event in a
136 /// [`tokio::select!`](crate::select) statement and some other branch
137 /// completes first, then it is guaranteed that no new connections were
138 /// accepted by this method.
139 ///
140 /// [`TcpStream`]: struct@crate::net::TcpStream
141 ///
142 /// # Examples
143 ///
144 /// ```no_run
145 /// use tokio::net::TcpListener;
146 ///
147 /// use std::io;
148 ///
149 /// #[tokio::main]
150 /// async fn main() -> io::Result<()> {
151 /// let listener = TcpListener::bind("127.0.0.1:8080").await?;
152 ///
153 /// match listener.accept().await {
154 /// Ok((_socket, addr)) => println!("new client: {:?}", addr),
155 /// Err(e) => println!("couldn't get client: {:?}", e),
156 /// }
157 ///
158 /// Ok(())
159 /// }
160 /// ```
161 pub async fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
162 let (mio, addr) = self
163 .io
164 .registration()
165 .async_io(Interest::READABLE, || self.io.accept())
166 .await?;
167
168 let stream = TcpStream::new(mio)?;
169 Ok((stream, addr))
170 }
171
172 /// Polls to accept a new incoming connection to this listener.
173 ///
174 /// If there is no connection to accept, `Poll::Pending` is returned and the
175 /// current task will be notified by a waker. Note that on multiple calls
176 /// to `poll_accept`, only the `Waker` from the `Context` passed to the most
177 /// recent call is scheduled to receive a wakeup.
178 pub fn poll_accept(&self, cx: &mut Context<'_>) -> Poll<io::Result<(TcpStream, SocketAddr)>> {
179 loop {
180 let ev = ready!(self.io.registration().poll_read_ready(cx))?;
181
182 match self.io.accept() {
183 Ok((io, addr)) => {
184 let io = TcpStream::new(io)?;
185 return Poll::Ready(Ok((io, addr)));
186 }
187 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
188 self.io.registration().clear_readiness(ev);
189 }
190 Err(e) => return Poll::Ready(Err(e)),
191 }
192 }
193 }
194
195 /// Creates new `TcpListener` from a `std::net::TcpListener`.
196 ///
197 /// This function is intended to be used to wrap a TCP listener from the
198 /// standard library in the Tokio equivalent.
199 ///
200 /// This API is typically paired with the `socket2` crate and the `Socket`
201 /// type to build up and customize a listener before it's shipped off to the
202 /// backing event loop. This allows configuration of options like
203 /// `SO_REUSEPORT`, binding to multiple addresses, etc.
204 ///
205 /// # Notes
206 ///
207 /// The caller is responsible for ensuring that the listener is in
208 /// non-blocking mode. Otherwise all I/O operations on the listener
209 /// will block the thread, which will cause unexpected behavior.
210 /// Non-blocking mode can be set using [`set_nonblocking`].
211 ///
212 /// [`set_nonblocking`]: std::net::TcpListener::set_nonblocking
213 ///
214 /// # Examples
215 ///
216 /// ```rust,no_run
217 /// use std::error::Error;
218 /// use tokio::net::TcpListener;
219 ///
220 /// #[tokio::main]
221 /// async fn main() -> Result<(), Box<dyn Error>> {
222 /// let std_listener = std::net::TcpListener::bind("127.0.0.1:0")?;
223 /// std_listener.set_nonblocking(true)?;
224 /// let listener = TcpListener::from_std(std_listener)?;
225 /// Ok(())
226 /// }
227 /// ```
228 ///
229 /// # Panics
230 ///
231 /// This function panics if it is not called from within a runtime with
232 /// IO enabled.
233 ///
234 /// The runtime is usually set implicitly when this function is called
235 /// from a future driven by a tokio runtime, otherwise runtime can be set
236 /// explicitly with [`Runtime::enter`](crate::runtime::Runtime::enter) function.
237 #[track_caller]
238 pub fn from_std(listener: net::TcpListener) -> io::Result<TcpListener> {
239 let io = mio::net::TcpListener::from_std(listener);
240 let io = PollEvented::new(io)?;
241 Ok(TcpListener { io })
242 }
243
244 /// Turns a [`tokio::net::TcpListener`] into a [`std::net::TcpListener`].
245 ///
246 /// The returned [`std::net::TcpListener`] will have nonblocking mode set as
247 /// `true`. Use [`set_nonblocking`] to change the blocking mode if needed.
248 ///
249 /// # Examples
250 ///
251 /// ```rust,no_run
252 /// use std::error::Error;
253 ///
254 /// #[tokio::main]
255 /// async fn main() -> Result<(), Box<dyn Error>> {
256 /// let tokio_listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?;
257 /// let std_listener = tokio_listener.into_std()?;
258 /// std_listener.set_nonblocking(false)?;
259 /// Ok(())
260 /// }
261 /// ```
262 ///
263 /// [`tokio::net::TcpListener`]: TcpListener
264 /// [`std::net::TcpListener`]: std::net::TcpListener
265 /// [`set_nonblocking`]: fn@std::net::TcpListener::set_nonblocking
266 pub fn into_std(self) -> io::Result<std::net::TcpListener> {
267 #[cfg(unix)]
268 {
269 use std::os::unix::io::{FromRawFd, IntoRawFd};
270 self.io
271 .into_inner()
272 .map(IntoRawFd::into_raw_fd)
273 .map(|raw_fd| unsafe { std::net::TcpListener::from_raw_fd(raw_fd) })
274 }
275
276 #[cfg(windows)]
277 {
278 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
279 self.io
280 .into_inner()
281 .map(|io| io.into_raw_socket())
282 .map(|raw_socket| unsafe { std::net::TcpListener::from_raw_socket(raw_socket) })
283 }
284
285 #[cfg(target_os = "wasi")]
286 {
287 use std::os::wasi::io::{FromRawFd, IntoRawFd};
288 self.io
289 .into_inner()
290 .map(|io| io.into_raw_fd())
291 .map(|raw_fd| unsafe { std::net::TcpListener::from_raw_fd(raw_fd) })
292 }
293 }
294
295 cfg_not_wasi! {
296 pub(crate) fn new(listener: mio::net::TcpListener) -> io::Result<TcpListener> {
297 let io = PollEvented::new(listener)?;
298 Ok(TcpListener { io })
299 }
300 }
301
302 /// Returns the local address that this listener is bound to.
303 ///
304 /// This can be useful, for example, when binding to port 0 to figure out
305 /// which port was actually bound.
306 ///
307 /// # Examples
308 ///
309 /// ```rust,no_run
310 /// use tokio::net::TcpListener;
311 ///
312 /// use std::io;
313 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
314 ///
315 /// #[tokio::main]
316 /// async fn main() -> io::Result<()> {
317 /// let listener = TcpListener::bind("127.0.0.1:8080").await?;
318 ///
319 /// assert_eq!(listener.local_addr()?,
320 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
321 ///
322 /// Ok(())
323 /// }
324 /// ```
325 pub fn local_addr(&self) -> io::Result<SocketAddr> {
326 self.io.local_addr()
327 }
328
329 /// Gets the value of the `IP_TTL` option for this socket.
330 ///
331 /// For more information about this option, see [`set_ttl`].
332 ///
333 /// [`set_ttl`]: method@Self::set_ttl
334 ///
335 /// # Examples
336 ///
337 /// ```no_run
338 /// use tokio::net::TcpListener;
339 ///
340 /// use std::io;
341 ///
342 /// #[tokio::main]
343 /// async fn main() -> io::Result<()> {
344 /// let listener = TcpListener::bind("127.0.0.1:0").await?;
345 ///
346 /// listener.set_ttl(100).expect("could not set TTL");
347 /// assert_eq!(listener.ttl()?, 100);
348 ///
349 /// Ok(())
350 /// }
351 /// ```
352 pub fn ttl(&self) -> io::Result<u32> {
353 self.io.ttl()
354 }
355
356 /// Sets the value for the `IP_TTL` option on this socket.
357 ///
358 /// This value sets the time-to-live field that is used in every packet sent
359 /// from this socket.
360 ///
361 /// # Examples
362 ///
363 /// ```no_run
364 /// use tokio::net::TcpListener;
365 ///
366 /// use std::io;
367 ///
368 /// #[tokio::main]
369 /// async fn main() -> io::Result<()> {
370 /// let listener = TcpListener::bind("127.0.0.1:0").await?;
371 ///
372 /// listener.set_ttl(100).expect("could not set TTL");
373 ///
374 /// Ok(())
375 /// }
376 /// ```
377 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
378 self.io.set_ttl(ttl)
379 }
380}
381
382impl TryFrom<net::TcpListener> for TcpListener {
383 type Error = io::Error;
384
385 /// Consumes stream, returning the tokio I/O object.
386 ///
387 /// This is equivalent to
388 /// [`TcpListener::from_std(stream)`](TcpListener::from_std).
389 fn try_from(stream: net::TcpListener) -> Result<Self, Self::Error> {
390 Self::from_std(stream)
391 }
392}
393
394impl fmt::Debug for TcpListener {
395 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396 self.io.fmt(f)
397 }
398}
399
400#[cfg(unix)]
401mod sys {
402 use super::TcpListener;
403 use std::os::unix::prelude::*;
404
405 impl AsRawFd for TcpListener {
406 fn as_raw_fd(&self) -> RawFd {
407 self.io.as_raw_fd()
408 }
409 }
410
411 impl AsFd for TcpListener {
412 fn as_fd(&self) -> BorrowedFd<'_> {
413 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
414 }
415 }
416}
417
418cfg_unstable! {
419 #[cfg(target_os = "wasi")]
420 mod sys {
421 use super::TcpListener;
422 use std::os::wasi::prelude::*;
423
424 impl AsRawFd for TcpListener {
425 fn as_raw_fd(&self) -> RawFd {
426 self.io.as_raw_fd()
427 }
428 }
429
430 impl AsFd for TcpListener {
431 fn as_fd(&self) -> BorrowedFd<'_> {
432 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
433 }
434 }
435 }
436}
437
438cfg_windows! {
439 use crate::os::windows::io::{AsRawSocket, RawSocket, AsSocket, BorrowedSocket};
440
441 impl AsRawSocket for TcpListener {
442 fn as_raw_socket(&self) -> RawSocket {
443 self.io.as_raw_socket()
444 }
445 }
446
447 impl AsSocket for TcpListener {
448 fn as_socket(&self) -> BorrowedSocket<'_> {
449 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
450 }
451 }
452}