@@ -18,26 +18,22 @@ use tokio_reactor::{Handle, PollEvented};
18
18
/// # Examples
19
19
///
20
20
/// ```no_run
21
- /// use futures::stream::Stream;
22
- /// use std::net::SocketAddr;
23
- /// use tokio::net::{TcpListener, TcpStream};
21
+ /// #![feature(async_await)]
24
22
///
25
- /// fn process_socket(socket: TcpStream) {
26
- /// // ...
27
- /// }
23
+ /// use tokio::net::TcpListener;
24
+ /// use std::error::Error;
25
+ /// # async fn process_socket<T>(socket: T) { }
28
26
///
29
- /// let addr = "127.0.0.1:8080".parse::<SocketAddr>()?;
30
- /// let listener = TcpListener::bind(&addr)?;
27
+ /// #[tokio::main]
28
+ /// async fn main() -> Result<(), Box<dyn Error>> {
29
+ /// let addr = "127.0.0.1:8080".parse()?;
30
+ /// let mut listener = TcpListener::bind(&addr)?;
31
31
///
32
- /// // accept connections and process them
33
- /// tokio::run(listener.incoming()
34
- /// .map_err(|e| eprintln!("failed to accept socket; error = {:?}", e))
35
- /// .for_each(|socket| {
32
+ /// loop {
33
+ /// let (socket, _) = listener.accept().await?;
36
34
/// process_socket(socket);
37
- /// Ok(())
38
- /// })
39
- /// );
40
- /// # Ok::<_, Box<dyn std::error::Error>>(())
35
+ /// }
36
+ /// }
41
37
/// ```
42
38
pub struct TcpListener {
43
39
io : PollEvented < mio:: net:: TcpListener > ,
@@ -64,42 +60,38 @@ impl TcpListener {
64
60
Ok ( TcpListener :: new ( l) )
65
61
}
66
62
67
- /// Attempt to accept a connection and create a new connected `TcpStream` if
68
- /// successful.
69
- ///
70
- /// Note that typically for simple usage it's easier to treat incoming
71
- /// connections as a `Stream` of `TcpStream`s with the `incoming` method
72
- /// below.
73
- ///
74
- /// # Return
75
- ///
76
- /// On success, returns `Ok(Async::Ready((socket, addr)))`.
77
- ///
78
- /// If the listener is not ready to accept, the method returns
79
- /// `Ok(Async::NotReady)` and arranges for the current task to receive a
80
- /// notification when the listener becomes ready to accept.
63
+ /// Accept a new incoming connection from this listener.
81
64
///
82
- /// # Panics
65
+ /// This function will yield once a new TCP connection is established. When
66
+ /// established, the corresponding [`TcpStream`] and the remote peer's
67
+ /// address will be returned.
83
68
///
84
- /// This function will panic if called from outside of a task context.
69
+ /// [`TcpStream`]: ../struct.TcpStream.html
85
70
///
86
71
/// # Examples
87
72
///
88
- /// ```no_run
89
- /// use std::net::SocketAddr;
73
+ /// ```
74
+ /// #![feature(async_await)]
75
+ ///
76
+ /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
90
77
/// use tokio::net::TcpListener;
91
- /// use futures::Async;
92
78
///
93
- /// let addr = "127.0.0.1:0 ".parse::<SocketAddr> ()?;
79
+ /// let addr = "127.0.0.1:8080 ".parse()?;
94
80
/// let mut listener = TcpListener::bind(&addr)?;
95
- /// match listener.poll_accept() {
96
- /// Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
97
- /// Ok(Async::NotReady) => println!("listener not ready to accept!"),
98
- /// Err(e) => eprintln!("got an error: {}", e),
81
+ /// match listener.accept().await {
82
+ /// Ok((_socket, addr)) => println!("new client: {:?}", addr),
83
+ /// Err(e) => println!("couldn't get client: {:?}", e),
99
84
/// }
100
- /// # Ok::<_, Box<dyn std::error::Error>>(())
85
+ /// # Ok(())
86
+ /// # }
101
87
/// ```
102
- pub fn poll_accept (
88
+ #[ allow( clippy:: needless_lifetimes) ] // false positive: https://github.com/rust-lang/rust-clippy/issues/3988
89
+ pub async fn accept ( & mut self ) -> io:: Result < ( TcpStream , SocketAddr ) > {
90
+ use async_util:: future:: poll_fn;
91
+ poll_fn ( |cx| self . poll_accept ( cx) ) . await
92
+ }
93
+
94
+ pub ( crate ) fn poll_accept (
103
95
& mut self ,
104
96
cx : & mut Context < ' _ > ,
105
97
) -> Poll < io:: Result < ( TcpStream , SocketAddr ) > > {
@@ -111,62 +103,7 @@ impl TcpListener {
111
103
Poll :: Ready ( Ok ( ( io, addr) ) )
112
104
}
113
105
114
- /// Accept a new incoming connection from this listener.
115
- ///
116
- /// This function will yield once a new TCP connection is established. When
117
- /// established, the corresponding [`TcpStream`] and the remote peer's
118
- /// address will be returned.
119
- ///
120
- /// [`TcpStream`]: ../struct.TcpStream.html
121
- ///
122
- /// # Examples
123
- ///
124
- /// ```
125
- /// unimplemented!();
126
- /// ```
127
- #[ allow( clippy:: needless_lifetimes) ] // false positive: https://github.com/rust-lang/rust-clippy/issues/3988
128
- pub async fn accept ( & mut self ) -> io:: Result < ( TcpStream , SocketAddr ) > {
129
- use async_util:: future:: poll_fn;
130
- poll_fn ( |cx| self . poll_accept ( cx) ) . await
131
- }
132
-
133
- /// Attempt to accept a connection and create a new connected `TcpStream` if
134
- /// successful.
135
- ///
136
- /// This function is the same as `accept` above except that it returns a
137
- /// `std::net::TcpStream` instead of a `tokio::net::TcpStream`. This in turn
138
- /// can then allow for the TCP stream to be associated with a different
139
- /// reactor than the one this `TcpListener` is associated with.
140
- ///
141
- /// # Return
142
- ///
143
- /// On success, returns `Ok(Async::Ready((socket, addr)))`.
144
- ///
145
- /// If the listener is not ready to accept, the method returns
146
- /// `Ok(Async::NotReady)` and arranges for the current task to receive a
147
- /// notification when the listener becomes ready to accept.
148
- ///
149
- /// # Panics
150
- ///
151
- /// This function will panic if called from outside of a task context.
152
- ///
153
- /// # Examples
154
- ///
155
- /// ```no_run
156
- /// use std::net::SocketAddr;
157
- /// use tokio::net::TcpListener;
158
- /// use futures::Async;
159
- ///
160
- /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
161
- /// let mut listener = TcpListener::bind(&addr)?;
162
- /// match listener.poll_accept_std() {
163
- /// Ok(Async::Ready((_socket, addr))) => println!("listener ready to accept: {:?}", addr),
164
- /// Ok(Async::NotReady) => println!("listener not ready to accept!"),
165
- /// Err(e) => eprintln!("got an error: {}", e),
166
- /// }
167
- /// # Ok::<_, Box<dyn std::error::Error>>(())
168
- /// ```
169
- pub fn poll_accept_std (
106
+ fn poll_accept_std (
170
107
& mut self ,
171
108
cx : & mut Context < ' _ > ,
172
109
) -> Poll < io:: Result < ( net:: TcpStream , SocketAddr ) > > {
@@ -267,28 +204,6 @@ impl TcpListener {
267
204
/// necessarily fatal ‒ for example having too many open file descriptors or the other side
268
205
/// closing the connection while it waits in an accept queue. These would terminate the stream
269
206
/// if not handled in any way.
270
- ///
271
- /// If aiming for production, decision what to do about them must be made. The
272
- /// [`tk-listen`](https://crates.io/crates/tk-listen) crate might be of some help.
273
- ///
274
- /// # Examples
275
- ///
276
- /// ```
277
- /// use tokio::net::TcpListener;
278
- /// use futures::stream::Stream;
279
- /// use std::net::SocketAddr;
280
- ///
281
- /// let addr = "127.0.0.1:0".parse::<SocketAddr>()?;
282
- /// let listener = TcpListener::bind(&addr)?;
283
- ///
284
- /// listener.incoming()
285
- /// .map_err(|e| eprintln!("failed to accept stream; error = {:?}", e))
286
- /// .for_each(|_socket| {
287
- /// println!("new socket!");
288
- /// Ok(())
289
- /// });
290
- /// # Ok::<_, Box<dyn std::error::Error>>(())
291
- /// ```
292
207
#[ cfg( feature = "async-traits" ) ]
293
208
pub fn incoming ( self ) -> Incoming {
294
209
Incoming :: new ( self )
0 commit comments