]> git.proxmox.com Git - rustc.git/blame - src/libstd/net/tcp.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / libstd / net / tcp.rs
CommitLineData
85aaf69f
SL
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
85aaf69f
SL
11use io::prelude::*;
12
d9579d0f 13use fmt;
85aaf69f
SL
14use io;
15use net::{ToSocketAddrs, SocketAddr, Shutdown};
d9579d0f 16use sys_common::net as net_imp;
c1a9b12d 17use sys_common::{AsInner, FromInner, IntoInner};
62682a34 18use time::Duration;
85aaf69f
SL
19
20/// A structure which represents a TCP stream between a local socket and a
21/// remote socket.
22///
23/// The socket will be closed when the value is dropped.
24///
c34b1796 25/// # Examples
85aaf69f
SL
26///
27/// ```no_run
28/// use std::io::prelude::*;
29/// use std::net::TcpStream;
30///
31/// {
32/// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
33///
34/// // ignore the Result
35/// let _ = stream.write(&[1]);
36/// let _ = stream.read(&mut [0; 128]); // ignore here too
37/// } // the stream is closed here
38/// ```
c34b1796 39#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
40pub struct TcpStream(net_imp::TcpStream);
41
42/// A structure representing a socket server.
43///
44/// # Examples
45///
46/// ```no_run
47/// use std::net::{TcpListener, TcpStream};
85aaf69f
SL
48///
49/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
50///
51/// fn handle_client(stream: TcpStream) {
52/// // ...
53/// }
54///
32a655c1 55/// // accept connections and process them serially
85aaf69f
SL
56/// for stream in listener.incoming() {
57/// match stream {
58/// Ok(stream) => {
9e0c209e 59/// handle_client(stream);
85aaf69f
SL
60/// }
61/// Err(e) => { /* connection failed */ }
62/// }
63/// }
85aaf69f 64/// ```
c34b1796 65#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
66pub struct TcpListener(net_imp::TcpListener);
67
68/// An infinite iterator over the connections from a `TcpListener`.
69///
476ff2be 70/// This iterator will infinitely yield [`Some`] of the accepted connections. It
85aaf69f 71/// is equivalent to calling `accept` in a loop.
5bcae85e
SL
72///
73/// This `struct` is created by the [`incoming`] method on [`TcpListener`].
74///
476ff2be 75/// [`Some`]: ../../std/option/enum.Option.html#variant.Some
5bcae85e
SL
76/// [`incoming`]: struct.TcpListener.html#method.incoming
77/// [`TcpListener`]: struct.TcpListener.html
c34b1796 78#[stable(feature = "rust1", since = "1.0.0")]
32a655c1 79#[derive(Debug)]
85aaf69f
SL
80pub struct Incoming<'a> { listener: &'a TcpListener }
81
82impl TcpStream {
9346a6ac 83 /// Opens a TCP connection to a remote host.
85aaf69f
SL
84 ///
85 /// `addr` is an address of the remote host. Anything which implements
86 /// `ToSocketAddrs` trait can be supplied for the address; see this trait
87 /// documentation for concrete examples.
a7813a04
XL
88 /// In case `ToSocketAddrs::to_socket_addrs()` returns more than one entry,
89 /// then the first valid and reachable address is used.
476ff2be
SL
90 ///
91 /// # Examples
92 ///
93 /// ```no_run
94 /// use std::net::TcpStream;
95 ///
96 /// if let Ok(stream) = TcpStream::connect("127.0.0.1:8080") {
97 /// println!("Connected to the server!");
98 /// } else {
99 /// println!("Couldn't connect to server...");
100 /// }
101 /// ```
c34b1796
AL
102 #[stable(feature = "rust1", since = "1.0.0")]
103 pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
85aaf69f
SL
104 super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
105 }
106
107 /// Returns the socket address of the remote peer of this TCP connection.
476ff2be
SL
108 ///
109 /// # Examples
110 ///
111 /// ```no_run
112 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream};
113 ///
114 /// let stream = TcpStream::connect("127.0.0.1:8080")
115 /// .expect("Couldn't connect to the server...");
116 /// assert_eq!(stream.peer_addr().unwrap(),
117 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
118 /// ```
c34b1796 119 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
120 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
121 self.0.peer_addr()
122 }
123
124 /// Returns the socket address of the local half of this TCP connection.
476ff2be
SL
125 ///
126 /// # Examples
127 ///
128 /// ```no_run
129 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpStream};
130 ///
131 /// let stream = TcpStream::connect("127.0.0.1:8080")
132 /// .expect("Couldn't connect to the server...");
133 /// assert_eq!(stream.local_addr().unwrap(),
134 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
135 /// ```
c34b1796
AL
136 #[stable(feature = "rust1", since = "1.0.0")]
137 pub fn local_addr(&self) -> io::Result<SocketAddr> {
85aaf69f
SL
138 self.0.socket_addr()
139 }
140
9346a6ac 141 /// Shuts down the read, write, or both halves of this connection.
85aaf69f
SL
142 ///
143 /// This function will cause all pending and future I/O on the specified
144 /// portions to return immediately with an appropriate value (see the
476ff2be
SL
145 /// documentation of [`Shutdown`]).
146 ///
147 /// [`Shutdown`]: ../../std/net/enum.Shutdown.html
148 ///
149 /// # Examples
150 ///
151 /// ```no_run
152 /// use std::net::{Shutdown, TcpStream};
153 ///
154 /// let stream = TcpStream::connect("127.0.0.1:8080")
155 /// .expect("Couldn't connect to the server...");
156 /// stream.shutdown(Shutdown::Both).expect("shutdown call failed");
157 /// ```
c34b1796 158 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
159 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
160 self.0.shutdown(how)
161 }
162
9346a6ac 163 /// Creates a new independently owned handle to the underlying socket.
85aaf69f
SL
164 ///
165 /// The returned `TcpStream` is a reference to the same stream that this
166 /// object references. Both handles will read and write the same stream of
167 /// data, and options set on one stream will be propagated to the other
168 /// stream.
476ff2be
SL
169 ///
170 /// # Examples
171 ///
172 /// ```no_run
173 /// use std::net::TcpStream;
174 ///
175 /// let stream = TcpStream::connect("127.0.0.1:8080")
176 /// .expect("Couldn't connect to the server...");
177 /// let stream_clone = stream.try_clone().expect("clone failed...");
178 /// ```
c34b1796 179 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
180 pub fn try_clone(&self) -> io::Result<TcpStream> {
181 self.0.duplicate().map(TcpStream)
182 }
183
62682a34
SL
184 /// Sets the read timeout to the timeout specified.
185 ///
476ff2be 186 /// If the value specified is [`None`], then [`read()`] calls will block
62682a34
SL
187 /// indefinitely. It is an error to pass the zero `Duration` to this
188 /// method.
e9174d1e
SL
189 ///
190 /// # Note
191 ///
192 /// Platforms may return a different error code whenever a read times out as
193 /// a result of setting this option. For example Unix typically returns an
476ff2be
SL
194 /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
195 ///
196 /// [`None`]: ../../std/option/enum.Option.html#variant.None
197 /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
198 /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
199 /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
200 ///
201 /// # Examples
202 ///
203 /// ```no_run
204 /// use std::net::TcpStream;
205 ///
206 /// let stream = TcpStream::connect("127.0.0.1:8080")
207 /// .expect("Couldn't connect to the server...");
208 /// stream.set_read_timeout(None).expect("set_read_timeout call failed");
209 /// ```
e9174d1e 210 #[stable(feature = "socket_timeout", since = "1.4.0")]
62682a34
SL
211 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
212 self.0.set_read_timeout(dur)
213 }
214
215 /// Sets the write timeout to the timeout specified.
216 ///
476ff2be
SL
217 /// If the value specified is [`None`], then [`write()`] calls will block
218 /// indefinitely. It is an error to pass the zero [`Duration`] to this
62682a34 219 /// method.
e9174d1e
SL
220 ///
221 /// # Note
222 ///
223 /// Platforms may return a different error code whenever a write times out
224 /// as a result of setting this option. For example Unix typically returns
476ff2be
SL
225 /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
226 ///
227 /// [`None`]: ../../std/option/enum.Option.html#variant.None
228 /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
229 /// [`Duration`]: ../../std/time/struct.Duration.html
230 /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
231 /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
232 ///
233 /// # Examples
234 ///
235 /// ```no_run
236 /// use std::net::TcpStream;
237 ///
238 /// let stream = TcpStream::connect("127.0.0.1:8080")
239 /// .expect("Couldn't connect to the server...");
240 /// stream.set_write_timeout(None).expect("set_write_timeout call failed");
241 /// ```
e9174d1e 242 #[stable(feature = "socket_timeout", since = "1.4.0")]
62682a34
SL
243 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
244 self.0.set_write_timeout(dur)
245 }
246
247 /// Returns the read timeout of this socket.
248 ///
476ff2be 249 /// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
62682a34
SL
250 ///
251 /// # Note
252 ///
253 /// Some platforms do not provide access to the current timeout.
476ff2be
SL
254 ///
255 /// [`None`]: ../../std/option/enum.Option.html#variant.None
256 /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
257 ///
258 /// # Examples
259 ///
260 /// ```no_run
261 /// use std::net::TcpStream;
262 ///
263 /// let stream = TcpStream::connect("127.0.0.1:8080")
264 /// .expect("Couldn't connect to the server...");
265 /// stream.set_read_timeout(None).expect("set_read_timeout call failed");
266 /// assert_eq!(stream.read_timeout().unwrap(), None);
267 /// ```
e9174d1e 268 #[stable(feature = "socket_timeout", since = "1.4.0")]
62682a34
SL
269 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
270 self.0.read_timeout()
271 }
272
273 /// Returns the write timeout of this socket.
274 ///
476ff2be 275 /// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
62682a34
SL
276 ///
277 /// # Note
278 ///
279 /// Some platforms do not provide access to the current timeout.
476ff2be
SL
280 ///
281 /// [`None`]: ../../std/option/enum.Option.html#variant.None
282 /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
283 ///
284 /// # Examples
285 ///
286 /// ```no_run
287 /// use std::net::TcpStream;
288 ///
289 /// let stream = TcpStream::connect("127.0.0.1:8080")
290 /// .expect("Couldn't connect to the server...");
291 /// stream.set_write_timeout(None).expect("set_write_timeout call failed");
292 /// assert_eq!(stream.write_timeout().unwrap(), None);
293 /// ```
e9174d1e 294 #[stable(feature = "socket_timeout", since = "1.4.0")]
62682a34
SL
295 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
296 self.0.write_timeout()
297 }
54a0048b 298
8bb4bdeb
XL
299 /// Receives data on the socket from the remote adress to which it is
300 /// connected, without removing that data from the queue. On success,
301 /// returns the number of bytes peeked.
302 ///
303 /// Successive calls return the same data. This is accomplished by passing
304 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
305 ///
306 /// # Examples
307 ///
308 /// ```no_run
309 /// #![feature(peek)]
310 /// use std::net::TcpStream;
311 ///
312 /// let stream = TcpStream::connect("127.0.0.1:8000")
313 /// .expect("couldn't bind to address");
314 /// let mut buf = [0; 10];
315 /// let len = stream.peek(&mut buf).expect("peek failed");
316 /// ```
317 #[unstable(feature = "peek", issue = "38980")]
318 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
319 self.0.peek(buf)
320 }
321
54a0048b
SL
322 /// Sets the value of the `TCP_NODELAY` option on this socket.
323 ///
324 /// If set, this option disables the Nagle algorithm. This means that
325 /// segments are always sent as soon as possible, even if there is only a
326 /// small amount of data. When not set, data is buffered until there is a
327 /// sufficient amount to send out, thereby avoiding the frequent sending of
328 /// small packets.
476ff2be
SL
329 ///
330 /// # Examples
331 ///
332 /// ```no_run
333 /// use std::net::TcpStream;
334 ///
335 /// let stream = TcpStream::connect("127.0.0.1:8080")
336 /// .expect("Couldn't connect to the server...");
337 /// stream.set_nodelay(true).expect("set_nodelay call failed");
338 /// ```
54a0048b
SL
339 #[stable(feature = "net2_mutators", since = "1.9.0")]
340 pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
341 self.0.set_nodelay(nodelay)
342 }
343
344 /// Gets the value of the `TCP_NODELAY` option on this socket.
345 ///
346 /// For more information about this option, see [`set_nodelay`][link].
347 ///
348 /// [link]: #method.set_nodelay
476ff2be
SL
349 ///
350 /// # Examples
351 ///
352 /// ```no_run
353 /// use std::net::TcpStream;
354 ///
355 /// let stream = TcpStream::connect("127.0.0.1:8080")
356 /// .expect("Couldn't connect to the server...");
357 /// stream.set_nodelay(true).expect("set_nodelay call failed");
358 /// assert_eq!(stream.nodelay().unwrap_or(false), true);
359 /// ```
54a0048b
SL
360 #[stable(feature = "net2_mutators", since = "1.9.0")]
361 pub fn nodelay(&self) -> io::Result<bool> {
362 self.0.nodelay()
363 }
364
365 /// Sets the value for the `IP_TTL` option on this socket.
366 ///
367 /// This value sets the time-to-live field that is used in every packet sent
368 /// from this socket.
476ff2be
SL
369 ///
370 /// # Examples
371 ///
372 /// ```no_run
373 /// use std::net::TcpStream;
374 ///
375 /// let stream = TcpStream::connect("127.0.0.1:8080")
376 /// .expect("Couldn't connect to the server...");
377 /// stream.set_ttl(100).expect("set_ttl call failed");
378 /// ```
54a0048b
SL
379 #[stable(feature = "net2_mutators", since = "1.9.0")]
380 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
381 self.0.set_ttl(ttl)
382 }
383
384 /// Gets the value of the `IP_TTL` option for this socket.
385 ///
386 /// For more information about this option, see [`set_ttl`][link].
387 ///
388 /// [link]: #method.set_ttl
476ff2be
SL
389 ///
390 /// # Examples
391 ///
392 /// ```no_run
393 /// use std::net::TcpStream;
394 ///
395 /// let stream = TcpStream::connect("127.0.0.1:8080")
396 /// .expect("Couldn't connect to the server...");
397 /// stream.set_ttl(100).expect("set_ttl call failed");
398 /// assert_eq!(stream.ttl().unwrap_or(0), 100);
399 /// ```
54a0048b
SL
400 #[stable(feature = "net2_mutators", since = "1.9.0")]
401 pub fn ttl(&self) -> io::Result<u32> {
402 self.0.ttl()
403 }
404
405 /// Get the value of the `SO_ERROR` option on this socket.
406 ///
407 /// This will retrieve the stored error in the underlying socket, clearing
408 /// the field in the process. This can be useful for checking errors between
409 /// calls.
476ff2be
SL
410 ///
411 /// # Examples
412 ///
413 /// ```no_run
414 /// use std::net::TcpStream;
415 ///
416 /// let stream = TcpStream::connect("127.0.0.1:8080")
417 /// .expect("Couldn't connect to the server...");
418 /// stream.take_error().expect("No error was expected...");
419 /// ```
54a0048b
SL
420 #[stable(feature = "net2_mutators", since = "1.9.0")]
421 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
422 self.0.take_error()
423 }
424
425 /// Moves this TCP stream into or out of nonblocking mode.
426 ///
427 /// On Unix this corresponds to calling fcntl, and on Windows this
428 /// corresponds to calling ioctlsocket.
476ff2be
SL
429 ///
430 /// # Examples
431 ///
432 /// ```no_run
433 /// use std::net::TcpStream;
434 ///
435 /// let stream = TcpStream::connect("127.0.0.1:8080")
436 /// .expect("Couldn't connect to the server...");
437 /// stream.set_nonblocking(true).expect("set_nonblocking call failed");
438 /// ```
54a0048b
SL
439 #[stable(feature = "net2_mutators", since = "1.9.0")]
440 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
441 self.0.set_nonblocking(nonblocking)
442 }
85aaf69f
SL
443}
444
c34b1796 445#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
446impl Read for TcpStream {
447 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
c1a9b12d 448 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
54a0048b 449 self.0.read_to_end(buf)
c1a9b12d 450 }
85aaf69f 451}
c34b1796 452#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
453impl Write for TcpStream {
454 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
455 fn flush(&mut self) -> io::Result<()> { Ok(()) }
456}
c34b1796 457#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
458impl<'a> Read for &'a TcpStream {
459 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
c1a9b12d 460 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
54a0048b 461 self.0.read_to_end(buf)
c1a9b12d 462 }
85aaf69f 463}
c34b1796 464#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
465impl<'a> Write for &'a TcpStream {
466 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
467 fn flush(&mut self) -> io::Result<()> { Ok(()) }
468}
469
470impl AsInner<net_imp::TcpStream> for TcpStream {
471 fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
472}
473
c34b1796
AL
474impl FromInner<net_imp::TcpStream> for TcpStream {
475 fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
476}
477
c1a9b12d
SL
478impl IntoInner<net_imp::TcpStream> for TcpStream {
479 fn into_inner(self) -> net_imp::TcpStream { self.0 }
480}
481
92a42be0 482#[stable(feature = "rust1", since = "1.0.0")]
d9579d0f
AL
483impl fmt::Debug for TcpStream {
484 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
485 self.0.fmt(f)
486 }
487}
488
85aaf69f
SL
489impl TcpListener {
490 /// Creates a new `TcpListener` which will be bound to the specified
491 /// address.
492 ///
493 /// The returned listener is ready for accepting connections.
494 ///
495 /// Binding with a port number of 0 will request that the OS assigns a port
496 /// to this listener. The port allocated can be queried via the
92a42be0 497 /// `local_addr` method.
85aaf69f 498 ///
b039eaaf 499 /// The address type can be any implementor of `ToSocketAddrs` trait. See
85aaf69f 500 /// its documentation for concrete examples.
476ff2be
SL
501 ///
502 /// # Examples
503 ///
504 /// ```no_run
505 /// use std::net::TcpListener;
506 ///
507 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
508 /// ```
c34b1796
AL
509 #[stable(feature = "rust1", since = "1.0.0")]
510 pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
85aaf69f
SL
511 super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
512 }
513
514 /// Returns the local socket address of this listener.
476ff2be
SL
515 ///
516 /// # Examples
517 ///
518 /// ```no_run
519 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener};
520 ///
521 /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
522 /// assert_eq!(listener.local_addr().unwrap(),
523 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
524 /// ```
c34b1796
AL
525 #[stable(feature = "rust1", since = "1.0.0")]
526 pub fn local_addr(&self) -> io::Result<SocketAddr> {
85aaf69f
SL
527 self.0.socket_addr()
528 }
529
9346a6ac 530 /// Creates a new independently owned handle to the underlying socket.
85aaf69f
SL
531 ///
532 /// The returned `TcpListener` is a reference to the same socket that this
533 /// object references. Both handles can be used to accept incoming
534 /// connections and options set on one listener will affect the other.
476ff2be
SL
535 ///
536 /// # Examples
537 ///
538 /// ```no_run
539 /// use std::net::TcpListener;
540 ///
541 /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
542 /// let listener_clone = listener.try_clone().unwrap();
543 /// ```
c34b1796 544 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
545 pub fn try_clone(&self) -> io::Result<TcpListener> {
546 self.0.duplicate().map(TcpListener)
547 }
548
549 /// Accept a new incoming connection from this listener.
550 ///
551 /// This function will block the calling thread until a new TCP connection
552 /// is established. When established, the corresponding `TcpStream` and the
553 /// remote peer's address will be returned.
476ff2be
SL
554 ///
555 /// # Examples
556 ///
557 /// ```no_run
558 /// use std::net::TcpListener;
559 ///
560 /// let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
561 /// match listener.accept() {
562 /// Ok((_socket, addr)) => println!("new client: {:?}", addr),
563 /// Err(e) => println!("couldn't get client: {:?}", e),
564 /// }
565 /// ```
c34b1796 566 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
567 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
568 self.0.accept().map(|(a, b)| (TcpStream(a), b))
569 }
570
571 /// Returns an iterator over the connections being received on this
572 /// listener.
573 ///
476ff2be
SL
574 /// The returned iterator will never return [`None`] and will also not yield
575 /// the peer's [`SocketAddr`] structure.
576 ///
577 /// [`None`]: ../../std/option/enum.Option.html#variant.None
578 /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
579 ///
580 /// # Examples
581 ///
582 /// ```no_run
583 /// use std::net::TcpListener;
584 ///
585 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
586 ///
587 /// for stream in listener.incoming() {
588 /// match stream {
589 /// Ok(stream) => {
590 /// println!("new client!");
591 /// }
592 /// Err(e) => { /* connection failed */ }
593 /// }
594 /// }
595 /// ```
c34b1796 596 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
597 pub fn incoming(&self) -> Incoming {
598 Incoming { listener: self }
599 }
54a0048b
SL
600
601 /// Sets the value for the `IP_TTL` option on this socket.
602 ///
603 /// This value sets the time-to-live field that is used in every packet sent
604 /// from this socket.
476ff2be
SL
605 ///
606 /// # Examples
607 ///
608 /// ```no_run
609 /// use std::net::TcpListener;
610 ///
611 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
612 /// listener.set_ttl(100).expect("could not set TTL");
613 /// ```
54a0048b
SL
614 #[stable(feature = "net2_mutators", since = "1.9.0")]
615 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
616 self.0.set_ttl(ttl)
617 }
618
619 /// Gets the value of the `IP_TTL` option for this socket.
620 ///
476ff2be 621 /// For more information about this option, see [`set_ttl()`][link].
54a0048b
SL
622 ///
623 /// [link]: #method.set_ttl
476ff2be
SL
624 ///
625 /// # Examples
626 ///
627 /// ```no_run
628 /// use std::net::TcpListener;
629 ///
630 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
631 /// listener.set_ttl(100).expect("could not set TTL");
632 /// assert_eq!(listener.ttl().unwrap_or(0), 100);
633 /// ```
54a0048b
SL
634 #[stable(feature = "net2_mutators", since = "1.9.0")]
635 pub fn ttl(&self) -> io::Result<u32> {
636 self.0.ttl()
637 }
638
54a0048b 639 #[stable(feature = "net2_mutators", since = "1.9.0")]
32a655c1
SL
640 #[rustc_deprecated(since = "1.16.0",
641 reason = "this option can only be set before the socket is bound")]
642 #[allow(missing_docs)]
54a0048b
SL
643 pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
644 self.0.set_only_v6(only_v6)
645 }
646
54a0048b 647 #[stable(feature = "net2_mutators", since = "1.9.0")]
32a655c1
SL
648 #[rustc_deprecated(since = "1.16.0",
649 reason = "this option can only be set before the socket is bound")]
650 #[allow(missing_docs)]
54a0048b
SL
651 pub fn only_v6(&self) -> io::Result<bool> {
652 self.0.only_v6()
653 }
654
655 /// Get the value of the `SO_ERROR` option on this socket.
656 ///
657 /// This will retrieve the stored error in the underlying socket, clearing
658 /// the field in the process. This can be useful for checking errors between
659 /// calls.
476ff2be
SL
660 ///
661 /// # Examples
662 ///
663 /// ```no_run
664 /// use std::net::TcpListener;
665 ///
666 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
667 /// listener.take_error().expect("No error was expected");
668 /// ```
54a0048b
SL
669 #[stable(feature = "net2_mutators", since = "1.9.0")]
670 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
671 self.0.take_error()
672 }
673
674 /// Moves this TCP stream into or out of nonblocking mode.
675 ///
676 /// On Unix this corresponds to calling fcntl, and on Windows this
677 /// corresponds to calling ioctlsocket.
476ff2be
SL
678 ///
679 /// # Examples
680 ///
681 /// ```no_run
682 /// use std::net::TcpListener;
683 ///
684 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
685 /// listener.set_nonblocking(true).expect("Cannot set non-blocking");
686 /// ```
54a0048b
SL
687 #[stable(feature = "net2_mutators", since = "1.9.0")]
688 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
689 self.0.set_nonblocking(nonblocking)
690 }
85aaf69f
SL
691}
692
c34b1796 693#[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
694impl<'a> Iterator for Incoming<'a> {
695 type Item = io::Result<TcpStream>;
696 fn next(&mut self) -> Option<io::Result<TcpStream>> {
697 Some(self.listener.accept().map(|p| p.0))
698 }
699}
700
701impl AsInner<net_imp::TcpListener> for TcpListener {
702 fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
703}
704
c34b1796
AL
705impl FromInner<net_imp::TcpListener> for TcpListener {
706 fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
707 TcpListener(inner)
708 }
709}
710
c1a9b12d
SL
711impl IntoInner<net_imp::TcpListener> for TcpListener {
712 fn into_inner(self) -> net_imp::TcpListener { self.0 }
713}
714
92a42be0 715#[stable(feature = "rust1", since = "1.0.0")]
d9579d0f
AL
716impl fmt::Debug for TcpListener {
717 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
718 self.0.fmt(f)
719 }
720}
721
c30ab7b3 722#[cfg(all(test, not(target_os = "emscripten")))]
85aaf69f 723mod tests {
85aaf69f
SL
724 use io::ErrorKind;
725 use io::prelude::*;
726 use net::*;
727 use net::test::{next_test_ip4, next_test_ip6};
728 use sync::mpsc::channel;
d9579d0f 729 use sys_common::AsInner;
9cc50fc6 730 use time::{Instant, Duration};
85aaf69f
SL
731 use thread;
732
733 fn each_ip(f: &mut FnMut(SocketAddr)) {
734 f(next_test_ip4());
735 f(next_test_ip6());
736 }
737
738 macro_rules! t {
739 ($e:expr) => {
740 match $e {
741 Ok(t) => t,
742 Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
743 }
744 }
745 }
746
85aaf69f
SL
747 #[test]
748 fn bind_error() {
c34b1796 749 match TcpListener::bind("1.1.1.1:9999") {
85aaf69f 750 Ok(..) => panic!(),
c34b1796
AL
751 Err(e) =>
752 assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
85aaf69f
SL
753 }
754 }
755
756 #[test]
757 fn connect_error() {
758 match TcpStream::connect("0.0.0.0:1") {
759 Ok(..) => panic!(),
c34b1796
AL
760 Err(e) => assert!(e.kind() == ErrorKind::ConnectionRefused ||
761 e.kind() == ErrorKind::InvalidInput ||
762 e.kind() == ErrorKind::AddrInUse ||
763 e.kind() == ErrorKind::AddrNotAvailable,
764 "bad error: {} {:?}", e, e.kind()),
85aaf69f
SL
765 }
766 }
767
768 #[test]
769 fn listen_localhost() {
770 let socket_addr = next_test_ip4();
771 let listener = t!(TcpListener::bind(&socket_addr));
772
773 let _t = thread::spawn(move || {
774 let mut stream = t!(TcpStream::connect(&("localhost",
775 socket_addr.port())));
776 t!(stream.write(&[144]));
777 });
778
779 let mut stream = t!(listener.accept()).0;
780 let mut buf = [0];
781 t!(stream.read(&mut buf));
782 assert!(buf[0] == 144);
783 }
784
785 #[test]
b039eaaf
SL
786 fn connect_loopback() {
787 each_ip(&mut |addr| {
788 let acceptor = t!(TcpListener::bind(&addr));
85aaf69f 789
b039eaaf
SL
790 let _t = thread::spawn(move|| {
791 let host = match addr {
792 SocketAddr::V4(..) => "127.0.0.1",
793 SocketAddr::V6(..) => "::1",
794 };
795 let mut stream = t!(TcpStream::connect(&(host, addr.port())));
796 t!(stream.write(&[66]));
797 });
85aaf69f 798
b039eaaf
SL
799 let mut stream = t!(acceptor.accept()).0;
800 let mut buf = [0];
801 t!(stream.read(&mut buf));
802 assert!(buf[0] == 66);
803 })
85aaf69f
SL
804 }
805
806 #[test]
b039eaaf 807 fn smoke_test() {
85aaf69f
SL
808 each_ip(&mut |addr| {
809 let acceptor = t!(TcpListener::bind(&addr));
810
811 let (tx, rx) = channel();
812 let _t = thread::spawn(move|| {
813 let mut stream = t!(TcpStream::connect(&addr));
814 t!(stream.write(&[99]));
c34b1796 815 tx.send(t!(stream.local_addr())).unwrap();
85aaf69f
SL
816 });
817
818 let (mut stream, addr) = t!(acceptor.accept());
819 let mut buf = [0];
820 t!(stream.read(&mut buf));
821 assert!(buf[0] == 99);
822 assert_eq!(addr, t!(rx.recv()));
823 })
824 }
825
826 #[test]
b039eaaf 827 fn read_eof() {
85aaf69f
SL
828 each_ip(&mut |addr| {
829 let acceptor = t!(TcpListener::bind(&addr));
830
831 let _t = thread::spawn(move|| {
832 let _stream = t!(TcpStream::connect(&addr));
833 // Close
834 });
835
836 let mut stream = t!(acceptor.accept()).0;
837 let mut buf = [0];
838 let nread = t!(stream.read(&mut buf));
839 assert_eq!(nread, 0);
840 let nread = t!(stream.read(&mut buf));
841 assert_eq!(nread, 0);
842 })
843 }
844
845 #[test]
846 fn write_close() {
847 each_ip(&mut |addr| {
848 let acceptor = t!(TcpListener::bind(&addr));
849
850 let (tx, rx) = channel();
851 let _t = thread::spawn(move|| {
852 drop(t!(TcpStream::connect(&addr)));
853 tx.send(()).unwrap();
854 });
855
856 let mut stream = t!(acceptor.accept()).0;
857 rx.recv().unwrap();
858 let buf = [0];
859 match stream.write(&buf) {
860 Ok(..) => {}
861 Err(e) => {
862 assert!(e.kind() == ErrorKind::ConnectionReset ||
863 e.kind() == ErrorKind::BrokenPipe ||
864 e.kind() == ErrorKind::ConnectionAborted,
865 "unknown error: {}", e);
866 }
867 }
868 })
869 }
870
871 #[test]
b039eaaf 872 fn multiple_connect_serial() {
85aaf69f
SL
873 each_ip(&mut |addr| {
874 let max = 10;
875 let acceptor = t!(TcpListener::bind(&addr));
876
877 let _t = thread::spawn(move|| {
878 for _ in 0..max {
879 let mut stream = t!(TcpStream::connect(&addr));
880 t!(stream.write(&[99]));
881 }
882 });
883
884 for stream in acceptor.incoming().take(max) {
885 let mut stream = t!(stream);
886 let mut buf = [0];
887 t!(stream.read(&mut buf));
888 assert_eq!(buf[0], 99);
889 }
890 })
891 }
892
893 #[test]
894 fn multiple_connect_interleaved_greedy_schedule() {
62682a34 895 const MAX: usize = 10;
85aaf69f
SL
896 each_ip(&mut |addr| {
897 let acceptor = t!(TcpListener::bind(&addr));
898
899 let _t = thread::spawn(move|| {
900 let acceptor = acceptor;
901 for (i, stream) in acceptor.incoming().enumerate().take(MAX) {
bd371182 902 // Start another thread to handle the connection
85aaf69f
SL
903 let _t = thread::spawn(move|| {
904 let mut stream = t!(stream);
905 let mut buf = [0];
906 t!(stream.read(&mut buf));
907 assert!(buf[0] == i as u8);
908 });
909 }
910 });
911
912 connect(0, addr);
913 });
914
915 fn connect(i: usize, addr: SocketAddr) {
916 if i == MAX { return }
917
918 let t = thread::spawn(move|| {
919 let mut stream = t!(TcpStream::connect(&addr));
920 // Connect again before writing
921 connect(i + 1, addr);
922 t!(stream.write(&[i as u8]));
923 });
924 t.join().ok().unwrap();
925 }
926 }
927
928 #[test]
b039eaaf 929 fn multiple_connect_interleaved_lazy_schedule() {
c34b1796 930 const MAX: usize = 10;
85aaf69f
SL
931 each_ip(&mut |addr| {
932 let acceptor = t!(TcpListener::bind(&addr));
933
934 let _t = thread::spawn(move|| {
935 for stream in acceptor.incoming().take(MAX) {
bd371182 936 // Start another thread to handle the connection
85aaf69f
SL
937 let _t = thread::spawn(move|| {
938 let mut stream = t!(stream);
939 let mut buf = [0];
940 t!(stream.read(&mut buf));
941 assert!(buf[0] == 99);
942 });
943 }
944 });
945
946 connect(0, addr);
947 });
948
949 fn connect(i: usize, addr: SocketAddr) {
950 if i == MAX { return }
951
952 let t = thread::spawn(move|| {
953 let mut stream = t!(TcpStream::connect(&addr));
954 connect(i + 1, addr);
955 t!(stream.write(&[99]));
956 });
957 t.join().ok().unwrap();
958 }
959 }
960
85aaf69f 961 #[test]
b039eaaf 962 fn socket_and_peer_name() {
85aaf69f
SL
963 each_ip(&mut |addr| {
964 let listener = t!(TcpListener::bind(&addr));
c34b1796 965 let so_name = t!(listener.local_addr());
85aaf69f
SL
966 assert_eq!(addr, so_name);
967 let _t = thread::spawn(move|| {
968 t!(listener.accept());
969 });
970
971 let stream = t!(TcpStream::connect(&addr));
972 assert_eq!(addr, t!(stream.peer_addr()));
973 })
974 }
975
976 #[test]
977 fn partial_read() {
978 each_ip(&mut |addr| {
979 let (tx, rx) = channel();
980 let srv = t!(TcpListener::bind(&addr));
981 let _t = thread::spawn(move|| {
982 let mut cl = t!(srv.accept()).0;
983 cl.write(&[10]).unwrap();
984 let mut b = [0];
985 t!(cl.read(&mut b));
986 tx.send(()).unwrap();
987 });
988
989 let mut c = t!(TcpStream::connect(&addr));
990 let mut b = [0; 10];
c34b1796 991 assert_eq!(c.read(&mut b).unwrap(), 1);
85aaf69f
SL
992 t!(c.write(&[1]));
993 rx.recv().unwrap();
994 })
995 }
996
997 #[test]
998 fn double_bind() {
999 each_ip(&mut |addr| {
1000 let _listener = t!(TcpListener::bind(&addr));
1001 match TcpListener::bind(&addr) {
1002 Ok(..) => panic!(),
1003 Err(e) => {
1004 assert!(e.kind() == ErrorKind::ConnectionRefused ||
c34b1796
AL
1005 e.kind() == ErrorKind::Other ||
1006 e.kind() == ErrorKind::AddrInUse,
85aaf69f
SL
1007 "unknown error: {} {:?}", e, e.kind());
1008 }
1009 }
1010 })
1011 }
1012
1013 #[test]
1014 fn fast_rebind() {
1015 each_ip(&mut |addr| {
1016 let acceptor = t!(TcpListener::bind(&addr));
1017
1018 let _t = thread::spawn(move|| {
1019 t!(TcpStream::connect(&addr));
1020 });
1021
1022 t!(acceptor.accept());
1023 drop(acceptor);
1024 t!(TcpListener::bind(&addr));
1025 });
1026 }
1027
1028 #[test]
1029 fn tcp_clone_smoke() {
1030 each_ip(&mut |addr| {
1031 let acceptor = t!(TcpListener::bind(&addr));
1032
1033 let _t = thread::spawn(move|| {
1034 let mut s = t!(TcpStream::connect(&addr));
1035 let mut buf = [0, 0];
c34b1796 1036 assert_eq!(s.read(&mut buf).unwrap(), 1);
85aaf69f
SL
1037 assert_eq!(buf[0], 1);
1038 t!(s.write(&[2]));
1039 });
1040
1041 let mut s1 = t!(acceptor.accept()).0;
1042 let s2 = t!(s1.try_clone());
1043
1044 let (tx1, rx1) = channel();
1045 let (tx2, rx2) = channel();
1046 let _t = thread::spawn(move|| {
1047 let mut s2 = s2;
1048 rx1.recv().unwrap();
1049 t!(s2.write(&[1]));
1050 tx2.send(()).unwrap();
1051 });
1052 tx1.send(()).unwrap();
1053 let mut buf = [0, 0];
c34b1796 1054 assert_eq!(s1.read(&mut buf).unwrap(), 1);
85aaf69f
SL
1055 rx2.recv().unwrap();
1056 })
1057 }
1058
1059 #[test]
1060 fn tcp_clone_two_read() {
1061 each_ip(&mut |addr| {
1062 let acceptor = t!(TcpListener::bind(&addr));
1063 let (tx1, rx) = channel();
1064 let tx2 = tx1.clone();
1065
1066 let _t = thread::spawn(move|| {
1067 let mut s = t!(TcpStream::connect(&addr));
1068 t!(s.write(&[1]));
1069 rx.recv().unwrap();
1070 t!(s.write(&[2]));
1071 rx.recv().unwrap();
1072 });
1073
1074 let mut s1 = t!(acceptor.accept()).0;
1075 let s2 = t!(s1.try_clone());
1076
1077 let (done, rx) = channel();
1078 let _t = thread::spawn(move|| {
1079 let mut s2 = s2;
1080 let mut buf = [0, 0];
1081 t!(s2.read(&mut buf));
1082 tx2.send(()).unwrap();
1083 done.send(()).unwrap();
1084 });
1085 let mut buf = [0, 0];
1086 t!(s1.read(&mut buf));
1087 tx1.send(()).unwrap();
1088
1089 rx.recv().unwrap();
1090 })
1091 }
1092
1093 #[test]
1094 fn tcp_clone_two_write() {
1095 each_ip(&mut |addr| {
1096 let acceptor = t!(TcpListener::bind(&addr));
1097
1098 let _t = thread::spawn(move|| {
1099 let mut s = t!(TcpStream::connect(&addr));
1100 let mut buf = [0, 1];
1101 t!(s.read(&mut buf));
1102 t!(s.read(&mut buf));
1103 });
1104
1105 let mut s1 = t!(acceptor.accept()).0;
1106 let s2 = t!(s1.try_clone());
1107
1108 let (done, rx) = channel();
1109 let _t = thread::spawn(move|| {
1110 let mut s2 = s2;
1111 t!(s2.write(&[1]));
1112 done.send(()).unwrap();
1113 });
1114 t!(s1.write(&[2]));
1115
1116 rx.recv().unwrap();
1117 })
1118 }
1119
1120 #[test]
1121 fn shutdown_smoke() {
1122 each_ip(&mut |addr| {
1123 let a = t!(TcpListener::bind(&addr));
1124 let _t = thread::spawn(move|| {
1125 let mut c = t!(a.accept()).0;
1126 let mut b = [0];
c34b1796 1127 assert_eq!(c.read(&mut b).unwrap(), 0);
85aaf69f
SL
1128 t!(c.write(&[1]));
1129 });
1130
1131 let mut s = t!(TcpStream::connect(&addr));
1132 t!(s.shutdown(Shutdown::Write));
1133 assert!(s.write(&[1]).is_err());
1134 let mut b = [0, 0];
1135 assert_eq!(t!(s.read(&mut b)), 1);
1136 assert_eq!(b[0], 1);
1137 })
1138 }
1139
1140 #[test]
1141 fn close_readwrite_smoke() {
1142 each_ip(&mut |addr| {
1143 let a = t!(TcpListener::bind(&addr));
1144 let (tx, rx) = channel::<()>();
1145 let _t = thread::spawn(move|| {
1146 let _s = t!(a.accept());
1147 let _ = rx.recv();
1148 });
1149
1150 let mut b = [0];
1151 let mut s = t!(TcpStream::connect(&addr));
1152 let mut s2 = t!(s.try_clone());
1153
1154 // closing should prevent reads/writes
1155 t!(s.shutdown(Shutdown::Write));
1156 assert!(s.write(&[0]).is_err());
1157 t!(s.shutdown(Shutdown::Read));
c34b1796 1158 assert_eq!(s.read(&mut b).unwrap(), 0);
85aaf69f
SL
1159
1160 // closing should affect previous handles
1161 assert!(s2.write(&[0]).is_err());
c34b1796 1162 assert_eq!(s2.read(&mut b).unwrap(), 0);
85aaf69f
SL
1163
1164 // closing should affect new handles
1165 let mut s3 = t!(s.try_clone());
1166 assert!(s3.write(&[0]).is_err());
c34b1796 1167 assert_eq!(s3.read(&mut b).unwrap(), 0);
85aaf69f
SL
1168
1169 // make sure these don't die
1170 let _ = s2.shutdown(Shutdown::Read);
1171 let _ = s2.shutdown(Shutdown::Write);
1172 let _ = s3.shutdown(Shutdown::Read);
1173 let _ = s3.shutdown(Shutdown::Write);
1174 drop(tx);
1175 })
1176 }
1177
1178 #[test]
32a655c1 1179 #[cfg(unix)] // test doesn't work on Windows, see #31657
85aaf69f
SL
1180 fn close_read_wakes_up() {
1181 each_ip(&mut |addr| {
1182 let a = t!(TcpListener::bind(&addr));
1183 let (tx1, rx) = channel::<()>();
1184 let _t = thread::spawn(move|| {
1185 let _s = t!(a.accept());
1186 let _ = rx.recv();
1187 });
1188
1189 let s = t!(TcpStream::connect(&addr));
1190 let s2 = t!(s.try_clone());
1191 let (tx, rx) = channel();
1192 let _t = thread::spawn(move|| {
1193 let mut s2 = s2;
1194 assert_eq!(t!(s2.read(&mut [0])), 0);
1195 tx.send(()).unwrap();
1196 });
bd371182 1197 // this should wake up the child thread
85aaf69f
SL
1198 t!(s.shutdown(Shutdown::Read));
1199
1200 // this test will never finish if the child doesn't wake up
1201 rx.recv().unwrap();
1202 drop(tx1);
1203 })
1204 }
1205
1206 #[test]
1207 fn clone_while_reading() {
1208 each_ip(&mut |addr| {
1209 let accept = t!(TcpListener::bind(&addr));
1210
bd371182 1211 // Enqueue a thread to write to a socket
85aaf69f
SL
1212 let (tx, rx) = channel();
1213 let (txdone, rxdone) = channel();
1214 let txdone2 = txdone.clone();
1215 let _t = thread::spawn(move|| {
1216 let mut tcp = t!(TcpStream::connect(&addr));
1217 rx.recv().unwrap();
1218 t!(tcp.write(&[0]));
1219 txdone2.send(()).unwrap();
1220 });
1221
1222 // Spawn off a reading clone
1223 let tcp = t!(accept.accept()).0;
1224 let tcp2 = t!(tcp.try_clone());
1225 let txdone3 = txdone.clone();
1226 let _t = thread::spawn(move|| {
1227 let mut tcp2 = tcp2;
1228 t!(tcp2.read(&mut [0]));
1229 txdone3.send(()).unwrap();
1230 });
1231
1232 // Try to ensure that the reading clone is indeed reading
1233 for _ in 0..50 {
1234 thread::yield_now();
1235 }
1236
1237 // clone the handle again while it's reading, then let it finish the
1238 // read.
1239 let _ = t!(tcp.try_clone());
1240 tx.send(()).unwrap();
1241 rxdone.recv().unwrap();
1242 rxdone.recv().unwrap();
1243 })
1244 }
1245
1246 #[test]
1247 fn clone_accept_smoke() {
1248 each_ip(&mut |addr| {
1249 let a = t!(TcpListener::bind(&addr));
1250 let a2 = t!(a.try_clone());
1251
1252 let _t = thread::spawn(move|| {
1253 let _ = TcpStream::connect(&addr);
1254 });
1255 let _t = thread::spawn(move|| {
1256 let _ = TcpStream::connect(&addr);
1257 });
1258
1259 t!(a.accept());
1260 t!(a2.accept());
1261 })
1262 }
1263
1264 #[test]
1265 fn clone_accept_concurrent() {
1266 each_ip(&mut |addr| {
1267 let a = t!(TcpListener::bind(&addr));
1268 let a2 = t!(a.try_clone());
1269
1270 let (tx, rx) = channel();
1271 let tx2 = tx.clone();
1272
1273 let _t = thread::spawn(move|| {
1274 tx.send(t!(a.accept())).unwrap();
1275 });
1276 let _t = thread::spawn(move|| {
1277 tx2.send(t!(a2.accept())).unwrap();
1278 });
1279
1280 let _t = thread::spawn(move|| {
1281 let _ = TcpStream::connect(&addr);
1282 });
1283 let _t = thread::spawn(move|| {
1284 let _ = TcpStream::connect(&addr);
1285 });
1286
1287 rx.recv().unwrap();
1288 rx.recv().unwrap();
1289 })
1290 }
d9579d0f
AL
1291
1292 #[test]
1293 fn debug() {
1294 let name = if cfg!(windows) {"socket"} else {"fd"};
1295 let socket_addr = next_test_ip4();
1296
1297 let listener = t!(TcpListener::bind(&socket_addr));
1298 let listener_inner = listener.0.socket().as_inner();
1299 let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}",
1300 socket_addr, name, listener_inner);
1301 assert_eq!(format!("{:?}", listener), compare);
1302
62682a34 1303 let stream = t!(TcpStream::connect(&("localhost",
d9579d0f
AL
1304 socket_addr.port())));
1305 let stream_inner = stream.0.socket().as_inner();
1306 let compare = format!("TcpStream {{ addr: {:?}, \
1307 peer: {:?}, {}: {:?} }}",
1308 stream.local_addr().unwrap(),
1309 stream.peer_addr().unwrap(),
1310 name,
1311 stream_inner);
1312 assert_eq!(format!("{:?}", stream), compare);
1313 }
62682a34
SL
1314
1315 // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
1316 // no longer has rounding errors.
c1a9b12d 1317 #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
62682a34
SL
1318 #[test]
1319 fn timeouts() {
1320 let addr = next_test_ip4();
1321 let listener = t!(TcpListener::bind(&addr));
1322
1323 let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1324 let dur = Duration::new(15410, 0);
1325
1326 assert_eq!(None, t!(stream.read_timeout()));
1327
1328 t!(stream.set_read_timeout(Some(dur)));
1329 assert_eq!(Some(dur), t!(stream.read_timeout()));
1330
1331 assert_eq!(None, t!(stream.write_timeout()));
1332
1333 t!(stream.set_write_timeout(Some(dur)));
1334 assert_eq!(Some(dur), t!(stream.write_timeout()));
1335
1336 t!(stream.set_read_timeout(None));
1337 assert_eq!(None, t!(stream.read_timeout()));
1338
1339 t!(stream.set_write_timeout(None));
1340 assert_eq!(None, t!(stream.write_timeout()));
9cc50fc6 1341 drop(listener);
62682a34
SL
1342 }
1343
1344 #[test]
1345 fn test_read_timeout() {
1346 let addr = next_test_ip4();
1347 let listener = t!(TcpListener::bind(&addr));
1348
1349 let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
1350 t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1351
1352 let mut buf = [0; 10];
9cc50fc6
SL
1353 let start = Instant::now();
1354 let kind = stream.read(&mut buf).err().expect("expected error").kind();
1355 assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
1356 assert!(start.elapsed() > Duration::from_millis(400));
1357 drop(listener);
62682a34
SL
1358 }
1359
1360 #[test]
1361 fn test_read_with_timeout() {
1362 let addr = next_test_ip4();
1363 let listener = t!(TcpListener::bind(&addr));
1364
1365 let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
1366 t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1367
1368 let mut other_end = t!(listener.accept()).0;
1369 t!(other_end.write_all(b"hello world"));
1370
1371 let mut buf = [0; 11];
1372 t!(stream.read(&mut buf));
1373 assert_eq!(b"hello world", &buf[..]);
1374
9cc50fc6
SL
1375 let start = Instant::now();
1376 let kind = stream.read(&mut buf).err().expect("expected error").kind();
1377 assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
1378 assert!(start.elapsed() > Duration::from_millis(400));
1379 drop(listener);
62682a34 1380 }
54a0048b
SL
1381
1382 #[test]
1383 fn nodelay() {
1384 let addr = next_test_ip4();
1385 let _listener = t!(TcpListener::bind(&addr));
1386
1387 let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1388
1389 assert_eq!(false, t!(stream.nodelay()));
1390 t!(stream.set_nodelay(true));
1391 assert_eq!(true, t!(stream.nodelay()));
1392 t!(stream.set_nodelay(false));
1393 assert_eq!(false, t!(stream.nodelay()));
1394 }
1395
1396 #[test]
1397 fn ttl() {
1398 let ttl = 100;
1399
1400 let addr = next_test_ip4();
1401 let listener = t!(TcpListener::bind(&addr));
1402
1403 t!(listener.set_ttl(ttl));
1404 assert_eq!(ttl, t!(listener.ttl()));
1405
1406 let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1407
1408 t!(stream.set_ttl(ttl));
1409 assert_eq!(ttl, t!(stream.ttl()));
1410 }
1411
1412 #[test]
1413 fn set_nonblocking() {
1414 let addr = next_test_ip4();
1415 let listener = t!(TcpListener::bind(&addr));
1416
1417 t!(listener.set_nonblocking(true));
1418 t!(listener.set_nonblocking(false));
1419
1420 let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
1421
1422 t!(stream.set_nonblocking(false));
1423 t!(stream.set_nonblocking(true));
1424
1425 let mut buf = [0];
1426 match stream.read(&mut buf) {
1427 Ok(_) => panic!("expected error"),
1428 Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
1429 Err(e) => panic!("unexpected error {}", e),
1430 }
1431 }
8bb4bdeb
XL
1432
1433 #[test]
1434 fn peek() {
1435 each_ip(&mut |addr| {
1436 let (txdone, rxdone) = channel();
1437
1438 let srv = t!(TcpListener::bind(&addr));
1439 let _t = thread::spawn(move|| {
1440 let mut cl = t!(srv.accept()).0;
1441 cl.write(&[1,3,3,7]).unwrap();
1442 t!(rxdone.recv());
1443 });
1444
1445 let mut c = t!(TcpStream::connect(&addr));
1446 let mut b = [0; 10];
1447 for _ in 1..3 {
1448 let len = c.peek(&mut b).unwrap();
1449 assert_eq!(len, 4);
1450 }
1451 let len = c.read(&mut b).unwrap();
1452 assert_eq!(len, 4);
1453
1454 t!(c.set_nonblocking(true));
1455 match c.peek(&mut b) {
1456 Ok(_) => panic!("expected error"),
1457 Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
1458 Err(e) => panic!("unexpected error {}", e),
1459 }
1460 t!(txdone.send(()));
1461 })
1462 }
85aaf69f 1463}