1use crate::net::{TcpListener, TcpStream};
2
3use std::fmt;
4use std::io;
5use std::net::SocketAddr;
6
7#[cfg(unix)]
8use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
9use std::time::Duration;
10
11cfg_windows! {
12 use crate::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket, AsSocket, BorrowedSocket};
13}
14
15cfg_net! {
16 /// A TCP socket that has not yet been converted to a `TcpStream` or
17 /// `TcpListener`.
18 ///
19 /// `TcpSocket` wraps an operating system socket and enables the caller to
20 /// configure the socket before establishing a TCP connection or accepting
21 /// inbound connections. The caller is able to set socket option and explicitly
22 /// bind the socket with a socket address.
23 ///
24 /// The underlying socket is closed when the `TcpSocket` value is dropped.
25 ///
26 /// `TcpSocket` should only be used directly if the default configuration used
27 /// by `TcpStream::connect` and `TcpListener::bind` does not meet the required
28 /// use case.
29 ///
30 /// Calling `TcpStream::connect("127.0.0.1:8080")` is equivalent to:
31 ///
32 /// ```no_run
33 /// use tokio::net::TcpSocket;
34 ///
35 /// use std::io;
36 ///
37 /// #[tokio::main]
38 /// async fn main() -> io::Result<()> {
39 /// let addr = "127.0.0.1:8080".parse().unwrap();
40 ///
41 /// let socket = TcpSocket::new_v4()?;
42 /// let stream = socket.connect(addr).await?;
43 /// # drop(stream);
44 ///
45 /// Ok(())
46 /// }
47 /// ```
48 ///
49 /// Calling `TcpListener::bind("127.0.0.1:8080")` is equivalent to:
50 ///
51 /// ```no_run
52 /// use tokio::net::TcpSocket;
53 ///
54 /// use std::io;
55 ///
56 /// #[tokio::main]
57 /// async fn main() -> io::Result<()> {
58 /// let addr = "127.0.0.1:8080".parse().unwrap();
59 ///
60 /// let socket = TcpSocket::new_v4()?;
61 /// // On platforms with Berkeley-derived sockets, this allows to quickly
62 /// // rebind a socket, without needing to wait for the OS to clean up the
63 /// // previous one.
64 /// //
65 /// // On Windows, this allows rebinding sockets which are actively in use,
66 /// // which allows “socket hijacking”, so we explicitly don't set it here.
67 /// // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
68 /// socket.set_reuseaddr(true)?;
69 /// socket.bind(addr)?;
70 ///
71 /// let listener = socket.listen(1024)?;
72 /// # drop(listener);
73 ///
74 /// Ok(())
75 /// }
76 /// ```
77 ///
78 /// Setting socket options not explicitly provided by `TcpSocket` may be done by
79 /// accessing the `RawFd`/`RawSocket` using [`AsRawFd`]/[`AsRawSocket`] and
80 /// setting the option with a crate like [`socket2`].
81 ///
82 /// [`RawFd`]: https://doc.rust-lang.org/std/os/unix/io/type.RawFd.html
83 /// [`RawSocket`]: https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html
84 /// [`AsRawFd`]: https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html
85 /// [`AsRawSocket`]: https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html
86 /// [`socket2`]: https://docs.rs/socket2/
87 #[cfg_attr(docsrs, doc(alias = "connect_std"))]
88 pub struct TcpSocket {
89 inner: socket2::Socket,
90 }
91}
92
93impl TcpSocket {
94 /// Creates a new socket configured for IPv4.
95 ///
96 /// Calls `socket(2)` with `AF_INET` and `SOCK_STREAM`.
97 ///
98 /// # Returns
99 ///
100 /// On success, the newly created `TcpSocket` is returned. If an error is
101 /// encountered, it is returned instead.
102 ///
103 /// # Examples
104 ///
105 /// Create a new IPv4 socket and start listening.
106 ///
107 /// ```no_run
108 /// use tokio::net::TcpSocket;
109 ///
110 /// use std::io;
111 ///
112 /// #[tokio::main]
113 /// async fn main() -> io::Result<()> {
114 /// let addr = "127.0.0.1:8080".parse().unwrap();
115 /// let socket = TcpSocket::new_v4()?;
116 /// socket.bind(addr)?;
117 ///
118 /// let listener = socket.listen(128)?;
119 /// # drop(listener);
120 /// Ok(())
121 /// }
122 /// ```
123 pub fn new_v4() -> io::Result<TcpSocket> {
124 TcpSocket::new(socket2::Domain::IPV4)
125 }
126
127 /// Creates a new socket configured for IPv6.
128 ///
129 /// Calls `socket(2)` with `AF_INET6` and `SOCK_STREAM`.
130 ///
131 /// # Returns
132 ///
133 /// On success, the newly created `TcpSocket` is returned. If an error is
134 /// encountered, it is returned instead.
135 ///
136 /// # Examples
137 ///
138 /// Create a new IPv6 socket and start listening.
139 ///
140 /// ```no_run
141 /// use tokio::net::TcpSocket;
142 ///
143 /// use std::io;
144 ///
145 /// #[tokio::main]
146 /// async fn main() -> io::Result<()> {
147 /// let addr = "[::1]:8080".parse().unwrap();
148 /// let socket = TcpSocket::new_v6()?;
149 /// socket.bind(addr)?;
150 ///
151 /// let listener = socket.listen(128)?;
152 /// # drop(listener);
153 /// Ok(())
154 /// }
155 /// ```
156 pub fn new_v6() -> io::Result<TcpSocket> {
157 TcpSocket::new(socket2::Domain::IPV6)
158 }
159
160 fn new(domain: socket2::Domain) -> io::Result<TcpSocket> {
161 let ty = socket2::Type::STREAM;
162 #[cfg(any(
163 target_os = "android",
164 target_os = "dragonfly",
165 target_os = "freebsd",
166 target_os = "fuchsia",
167 target_os = "illumos",
168 target_os = "linux",
169 target_os = "netbsd",
170 target_os = "openbsd"
171 ))]
172 let ty = ty.nonblocking();
173 let inner = socket2::Socket::new(domain, ty, Some(socket2::Protocol::TCP))?;
174 #[cfg(not(any(
175 target_os = "android",
176 target_os = "dragonfly",
177 target_os = "freebsd",
178 target_os = "fuchsia",
179 target_os = "illumos",
180 target_os = "linux",
181 target_os = "netbsd",
182 target_os = "openbsd"
183 )))]
184 inner.set_nonblocking(true)?;
185 Ok(TcpSocket { inner })
186 }
187
188 /// Allows the socket to bind to an in-use address.
189 ///
190 /// Behavior is platform specific. Refer to the target platform's
191 /// documentation for more details.
192 ///
193 /// # Examples
194 ///
195 /// ```no_run
196 /// use tokio::net::TcpSocket;
197 ///
198 /// use std::io;
199 ///
200 /// #[tokio::main]
201 /// async fn main() -> io::Result<()> {
202 /// let addr = "127.0.0.1:8080".parse().unwrap();
203 ///
204 /// let socket = TcpSocket::new_v4()?;
205 /// socket.set_reuseaddr(true)?;
206 /// socket.bind(addr)?;
207 ///
208 /// let listener = socket.listen(1024)?;
209 /// # drop(listener);
210 ///
211 /// Ok(())
212 /// }
213 /// ```
214 pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
215 self.inner.set_reuse_address(reuseaddr)
216 }
217
218 /// Retrieves the value set for `SO_REUSEADDR` on this socket.
219 ///
220 /// # Examples
221 ///
222 /// ```no_run
223 /// use tokio::net::TcpSocket;
224 ///
225 /// use std::io;
226 ///
227 /// #[tokio::main]
228 /// async fn main() -> io::Result<()> {
229 /// let addr = "127.0.0.1:8080".parse().unwrap();
230 ///
231 /// let socket = TcpSocket::new_v4()?;
232 /// socket.set_reuseaddr(true)?;
233 /// assert!(socket.reuseaddr().unwrap());
234 /// socket.bind(addr)?;
235 ///
236 /// let listener = socket.listen(1024)?;
237 /// Ok(())
238 /// }
239 /// ```
240 pub fn reuseaddr(&self) -> io::Result<bool> {
241 self.inner.reuse_address()
242 }
243
244 /// Allows the socket to bind to an in-use port. Only available for unix systems
245 /// (excluding Solaris & Illumos).
246 ///
247 /// Behavior is platform specific. Refer to the target platform's
248 /// documentation for more details.
249 ///
250 /// # Examples
251 ///
252 /// ```no_run
253 /// use tokio::net::TcpSocket;
254 ///
255 /// use std::io;
256 ///
257 /// #[tokio::main]
258 /// async fn main() -> io::Result<()> {
259 /// let addr = "127.0.0.1:8080".parse().unwrap();
260 ///
261 /// let socket = TcpSocket::new_v4()?;
262 /// socket.set_reuseport(true)?;
263 /// socket.bind(addr)?;
264 ///
265 /// let listener = socket.listen(1024)?;
266 /// Ok(())
267 /// }
268 /// ```
269 #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
270 #[cfg_attr(
271 docsrs,
272 doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
273 )]
274 pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> {
275 self.inner.set_reuse_port(reuseport)
276 }
277
278 /// Allows the socket to bind to an in-use port. Only available for unix systems
279 /// (excluding Solaris & Illumos).
280 ///
281 /// Behavior is platform specific. Refer to the target platform's
282 /// documentation for more details.
283 ///
284 /// # Examples
285 ///
286 /// ```no_run
287 /// use tokio::net::TcpSocket;
288 ///
289 /// use std::io;
290 ///
291 /// #[tokio::main]
292 /// async fn main() -> io::Result<()> {
293 /// let addr = "127.0.0.1:8080".parse().unwrap();
294 ///
295 /// let socket = TcpSocket::new_v4()?;
296 /// socket.set_reuseport(true)?;
297 /// assert!(socket.reuseport().unwrap());
298 /// socket.bind(addr)?;
299 ///
300 /// let listener = socket.listen(1024)?;
301 /// Ok(())
302 /// }
303 /// ```
304 #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
305 #[cfg_attr(
306 docsrs,
307 doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
308 )]
309 pub fn reuseport(&self) -> io::Result<bool> {
310 self.inner.reuse_port()
311 }
312
313 /// Sets the size of the TCP send buffer on this socket.
314 ///
315 /// On most operating systems, this sets the `SO_SNDBUF` socket option.
316 pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> {
317 self.inner.set_send_buffer_size(size as usize)
318 }
319
320 /// Returns the size of the TCP send buffer for this socket.
321 ///
322 /// On most operating systems, this is the value of the `SO_SNDBUF` socket
323 /// option.
324 ///
325 /// Note that if [`set_send_buffer_size`] has been called on this socket
326 /// previously, the value returned by this function may not be the same as
327 /// the argument provided to `set_send_buffer_size`. This is for the
328 /// following reasons:
329 ///
330 /// * Most operating systems have minimum and maximum allowed sizes for the
331 /// send buffer, and will clamp the provided value if it is below the
332 /// minimum or above the maximum. The minimum and maximum buffer sizes are
333 /// OS-dependent.
334 /// * Linux will double the buffer size to account for internal bookkeeping
335 /// data, and returns the doubled value from `getsockopt(2)`. As per `man
336 /// 7 socket`:
337 /// > Sets or gets the maximum socket send buffer in bytes. The
338 /// > kernel doubles this value (to allow space for bookkeeping
339 /// > overhead) when it is set using `setsockopt(2)`, and this doubled
340 /// > value is returned by `getsockopt(2)`.
341 ///
342 /// [`set_send_buffer_size`]: #method.set_send_buffer_size
343 pub fn send_buffer_size(&self) -> io::Result<u32> {
344 self.inner.send_buffer_size().map(|n| n as u32)
345 }
346
347 /// Sets the size of the TCP receive buffer on this socket.
348 ///
349 /// On most operating systems, this sets the `SO_RCVBUF` socket option.
350 pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> {
351 self.inner.set_recv_buffer_size(size as usize)
352 }
353
354 /// Returns the size of the TCP receive buffer for this socket.
355 ///
356 /// On most operating systems, this is the value of the `SO_RCVBUF` socket
357 /// option.
358 ///
359 /// Note that if [`set_recv_buffer_size`] has been called on this socket
360 /// previously, the value returned by this function may not be the same as
361 /// the argument provided to `set_send_buffer_size`. This is for the
362 /// following reasons:
363 ///
364 /// * Most operating systems have minimum and maximum allowed sizes for the
365 /// receive buffer, and will clamp the provided value if it is below the
366 /// minimum or above the maximum. The minimum and maximum buffer sizes are
367 /// OS-dependent.
368 /// * Linux will double the buffer size to account for internal bookkeeping
369 /// data, and returns the doubled value from `getsockopt(2)`. As per `man
370 /// 7 socket`:
371 /// > Sets or gets the maximum socket send buffer in bytes. The
372 /// > kernel doubles this value (to allow space for bookkeeping
373 /// > overhead) when it is set using `setsockopt(2)`, and this doubled
374 /// > value is returned by `getsockopt(2)`.
375 ///
376 /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size
377 pub fn recv_buffer_size(&self) -> io::Result<u32> {
378 self.inner.recv_buffer_size().map(|n| n as u32)
379 }
380
381 /// Sets the linger duration of this socket by setting the `SO_LINGER` option.
382 ///
383 /// This option controls the action taken when a stream has unsent messages and the stream is
384 /// closed. If `SO_LINGER` is set, the system shall block the process until it can transmit the
385 /// data or until the time expires.
386 ///
387 /// If `SO_LINGER` is not specified, and the socket is closed, the system handles the call in a
388 /// way that allows the process to continue as quickly as possible.
389 pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
390 self.inner.set_linger(dur)
391 }
392
393 /// Reads the linger duration for this socket by getting the `SO_LINGER`
394 /// option.
395 ///
396 /// For more information about this option, see [`set_linger`].
397 ///
398 /// [`set_linger`]: TcpSocket::set_linger
399 pub fn linger(&self) -> io::Result<Option<Duration>> {
400 self.inner.linger()
401 }
402
403 /// Sets the value of the `TCP_NODELAY` option on this socket.
404 ///
405 /// If set, this option disables the Nagle algorithm. This means that segments are always
406 /// sent as soon as possible, even if there is only a small amount of data. When not set,
407 /// data is buffered until there is a sufficient amount to send out, thereby avoiding
408 /// the frequent sending of small packets.
409 ///
410 /// # Examples
411 ///
412 /// ```no_run
413 /// use tokio::net::TcpSocket;
414 ///
415 /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
416 /// let socket = TcpSocket::new_v4()?;
417 ///
418 /// println!("{:?}", socket.nodelay()?);
419 /// # Ok(())
420 /// # }
421 /// ```
422 pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
423 self.inner.set_nodelay(nodelay)
424 }
425
426 /// Gets the value of the `TCP_NODELAY` option on this socket.
427 ///
428 /// For more information about this option, see [`set_nodelay`].
429 ///
430 /// [`set_nodelay`]: TcpSocket::set_nodelay
431 ///
432 /// # Examples
433 ///
434 /// ```no_run
435 /// use tokio::net::TcpSocket;
436 ///
437 /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
438 /// let stream = TcpSocket::new_v4()?;
439 ///
440 /// stream.set_nodelay(true)?;
441 /// # Ok(())
442 /// # }
443 /// ```
444 pub fn nodelay(&self) -> io::Result<bool> {
445 self.inner.nodelay()
446 }
447
448 /// Gets the value of the `IP_TOS` option for this socket.
449 ///
450 /// For more information about this option, see [`set_tos`].
451 ///
452 /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
453 /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
454 ///
455 /// [`set_tos`]: Self::set_tos
456 // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1464
457 #[cfg(not(any(
458 target_os = "fuchsia",
459 target_os = "redox",
460 target_os = "solaris",
461 target_os = "illumos",
462 )))]
463 #[cfg_attr(
464 docsrs,
465 doc(cfg(not(any(
466 target_os = "fuchsia",
467 target_os = "redox",
468 target_os = "solaris",
469 target_os = "illumos",
470 ))))
471 )]
472 pub fn tos(&self) -> io::Result<u32> {
473 self.inner.tos()
474 }
475
476 /// Sets the value for the `IP_TOS` option on this socket.
477 ///
478 /// This value sets the type-of-service field that is used in every packet
479 /// sent from this socket.
480 ///
481 /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
482 /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
483 // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1446
484 #[cfg(not(any(
485 target_os = "fuchsia",
486 target_os = "redox",
487 target_os = "solaris",
488 target_os = "illumos",
489 )))]
490 #[cfg_attr(
491 docsrs,
492 doc(cfg(not(any(
493 target_os = "fuchsia",
494 target_os = "redox",
495 target_os = "solaris",
496 target_os = "illumos",
497 ))))
498 )]
499 pub fn set_tos(&self, tos: u32) -> io::Result<()> {
500 self.inner.set_tos(tos)
501 }
502
503 /// Gets the value for the `SO_BINDTODEVICE` option on this socket
504 ///
505 /// This value gets the socket binded device's interface name.
506 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
507 #[cfg_attr(
508 docsrs,
509 doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",)))
510 )]
511 pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
512 self.inner.device()
513 }
514
515 /// Sets the value for the `SO_BINDTODEVICE` option on this socket
516 ///
517 /// If a socket is bound to an interface, only packets received from that
518 /// particular interface are processed by the socket. Note that this only
519 /// works for some socket types, particularly `AF_INET` sockets.
520 ///
521 /// If `interface` is `None` or an empty string it removes the binding.
522 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
523 #[cfg_attr(
524 docsrs,
525 doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))
526 )]
527 pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
528 self.inner.bind_device(interface)
529 }
530
531 /// Gets the local address of this socket.
532 ///
533 /// Will fail on windows if called before `bind`.
534 ///
535 /// # Examples
536 ///
537 /// ```no_run
538 /// use tokio::net::TcpSocket;
539 ///
540 /// use std::io;
541 ///
542 /// #[tokio::main]
543 /// async fn main() -> io::Result<()> {
544 /// let addr = "127.0.0.1:8080".parse().unwrap();
545 ///
546 /// let socket = TcpSocket::new_v4()?;
547 /// socket.bind(addr)?;
548 /// assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
549 /// let listener = socket.listen(1024)?;
550 /// Ok(())
551 /// }
552 /// ```
553 pub fn local_addr(&self) -> io::Result<SocketAddr> {
554 self.inner.local_addr().and_then(convert_address)
555 }
556
557 /// Returns the value of the `SO_ERROR` option.
558 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
559 self.inner.take_error()
560 }
561
562 /// Binds the socket to the given address.
563 ///
564 /// This calls the `bind(2)` operating-system function. Behavior is
565 /// platform specific. Refer to the target platform's documentation for more
566 /// details.
567 ///
568 /// # Examples
569 ///
570 /// Bind a socket before listening.
571 ///
572 /// ```no_run
573 /// use tokio::net::TcpSocket;
574 ///
575 /// use std::io;
576 ///
577 /// #[tokio::main]
578 /// async fn main() -> io::Result<()> {
579 /// let addr = "127.0.0.1:8080".parse().unwrap();
580 ///
581 /// let socket = TcpSocket::new_v4()?;
582 /// socket.bind(addr)?;
583 ///
584 /// let listener = socket.listen(1024)?;
585 /// # drop(listener);
586 ///
587 /// Ok(())
588 /// }
589 /// ```
590 pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
591 self.inner.bind(&addr.into())
592 }
593
594 /// Establishes a TCP connection with a peer at the specified socket address.
595 ///
596 /// The `TcpSocket` is consumed. Once the connection is established, a
597 /// connected [`TcpStream`] is returned. If the connection fails, the
598 /// encountered error is returned.
599 ///
600 /// [`TcpStream`]: TcpStream
601 ///
602 /// This calls the `connect(2)` operating-system function. Behavior is
603 /// platform specific. Refer to the target platform's documentation for more
604 /// details.
605 ///
606 /// # Examples
607 ///
608 /// Connecting to a peer.
609 ///
610 /// ```no_run
611 /// use tokio::net::TcpSocket;
612 ///
613 /// use std::io;
614 ///
615 /// #[tokio::main]
616 /// async fn main() -> io::Result<()> {
617 /// let addr = "127.0.0.1:8080".parse().unwrap();
618 ///
619 /// let socket = TcpSocket::new_v4()?;
620 /// let stream = socket.connect(addr).await?;
621 /// # drop(stream);
622 ///
623 /// Ok(())
624 /// }
625 /// ```
626 pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
627 if let Err(err) = self.inner.connect(&addr.into()) {
628 #[cfg(unix)]
629 if err.raw_os_error() != Some(libc::EINPROGRESS) {
630 return Err(err);
631 }
632 #[cfg(windows)]
633 if err.kind() != io::ErrorKind::WouldBlock {
634 return Err(err);
635 }
636 }
637 #[cfg(unix)]
638 let mio = {
639 use std::os::unix::io::{FromRawFd, IntoRawFd};
640
641 let raw_fd = self.inner.into_raw_fd();
642 unsafe { mio::net::TcpStream::from_raw_fd(raw_fd) }
643 };
644
645 #[cfg(windows)]
646 let mio = {
647 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
648
649 let raw_socket = self.inner.into_raw_socket();
650 unsafe { mio::net::TcpStream::from_raw_socket(raw_socket) }
651 };
652
653 TcpStream::connect_mio(mio).await
654 }
655
656 /// Converts the socket into a `TcpListener`.
657 ///
658 /// `backlog` defines the maximum number of pending connections are queued
659 /// by the operating system at any given time. Connection are removed from
660 /// the queue with [`TcpListener::accept`]. When the queue is full, the
661 /// operating-system will start rejecting connections.
662 ///
663 /// [`TcpListener::accept`]: TcpListener::accept
664 ///
665 /// This calls the `listen(2)` operating-system function, marking the socket
666 /// as a passive socket. Behavior is platform specific. Refer to the target
667 /// platform's documentation for more details.
668 ///
669 /// # Examples
670 ///
671 /// Create a `TcpListener`.
672 ///
673 /// ```no_run
674 /// use tokio::net::TcpSocket;
675 ///
676 /// use std::io;
677 ///
678 /// #[tokio::main]
679 /// async fn main() -> io::Result<()> {
680 /// let addr = "127.0.0.1:8080".parse().unwrap();
681 ///
682 /// let socket = TcpSocket::new_v4()?;
683 /// socket.bind(addr)?;
684 ///
685 /// let listener = socket.listen(1024)?;
686 /// # drop(listener);
687 ///
688 /// Ok(())
689 /// }
690 /// ```
691 pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
692 self.inner.listen(backlog as i32)?;
693 #[cfg(unix)]
694 let mio = {
695 use std::os::unix::io::{FromRawFd, IntoRawFd};
696
697 let raw_fd = self.inner.into_raw_fd();
698 unsafe { mio::net::TcpListener::from_raw_fd(raw_fd) }
699 };
700
701 #[cfg(windows)]
702 let mio = {
703 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
704
705 let raw_socket = self.inner.into_raw_socket();
706 unsafe { mio::net::TcpListener::from_raw_socket(raw_socket) }
707 };
708
709 TcpListener::new(mio)
710 }
711
712 /// Converts a [`std::net::TcpStream`] into a `TcpSocket`. The provided
713 /// socket must not have been connected prior to calling this function. This
714 /// function is typically used together with crates such as [`socket2`] to
715 /// configure socket options that are not available on `TcpSocket`.
716 ///
717 /// [`std::net::TcpStream`]: struct@std::net::TcpStream
718 /// [`socket2`]: https://docs.rs/socket2/
719 ///
720 /// # Notes
721 ///
722 /// The caller is responsible for ensuring that the socket is in
723 /// non-blocking mode. Otherwise all I/O operations on the socket
724 /// will block the thread, which will cause unexpected behavior.
725 /// Non-blocking mode can be set using [`set_nonblocking`].
726 ///
727 /// [`set_nonblocking`]: std::net::TcpStream::set_nonblocking
728 ///
729 /// # Examples
730 ///
731 /// ```
732 /// use tokio::net::TcpSocket;
733 /// use socket2::{Domain, Socket, Type};
734 ///
735 /// #[tokio::main]
736 /// async fn main() -> std::io::Result<()> {
737 /// let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
738 /// socket2_socket.set_nonblocking(true)?;
739 ///
740 /// let socket = TcpSocket::from_std_stream(socket2_socket.into());
741 ///
742 /// Ok(())
743 /// }
744 /// ```
745 pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
746 #[cfg(unix)]
747 {
748 use std::os::unix::io::{FromRawFd, IntoRawFd};
749
750 let raw_fd = std_stream.into_raw_fd();
751 unsafe { TcpSocket::from_raw_fd(raw_fd) }
752 }
753
754 #[cfg(windows)]
755 {
756 use std::os::windows::io::{FromRawSocket, IntoRawSocket};
757
758 let raw_socket = std_stream.into_raw_socket();
759 unsafe { TcpSocket::from_raw_socket(raw_socket) }
760 }
761 }
762}
763
764fn convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr> {
765 match address.as_socket() {
766 Some(address) => Ok(address),
767 None => Err(io::Error::new(
768 io::ErrorKind::InvalidInput,
769 "invalid address family (not IPv4 or IPv6)",
770 )),
771 }
772}
773
774impl fmt::Debug for TcpSocket {
775 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
776 self.inner.fmt(fmt)
777 }
778}
779
780#[cfg(unix)]
781impl AsRawFd for TcpSocket {
782 fn as_raw_fd(&self) -> RawFd {
783 self.inner.as_raw_fd()
784 }
785}
786
787#[cfg(unix)]
788impl AsFd for TcpSocket {
789 fn as_fd(&self) -> BorrowedFd<'_> {
790 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
791 }
792}
793
794#[cfg(unix)]
795impl FromRawFd for TcpSocket {
796 /// Converts a `RawFd` to a `TcpSocket`.
797 ///
798 /// # Notes
799 ///
800 /// The caller is responsible for ensuring that the socket is in
801 /// non-blocking mode.
802 unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
803 let inner = socket2::Socket::from_raw_fd(fd);
804 TcpSocket { inner }
805 }
806}
807
808#[cfg(unix)]
809impl IntoRawFd for TcpSocket {
810 fn into_raw_fd(self) -> RawFd {
811 self.inner.into_raw_fd()
812 }
813}
814
815cfg_windows! {
816 impl IntoRawSocket for TcpSocket {
817 fn into_raw_socket(self) -> RawSocket {
818 self.inner.into_raw_socket()
819 }
820 }
821
822 impl AsRawSocket for TcpSocket {
823 fn as_raw_socket(&self) -> RawSocket {
824 self.inner.as_raw_socket()
825 }
826 }
827
828 impl AsSocket for TcpSocket {
829 fn as_socket(&self) -> BorrowedSocket<'_> {
830 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
831 }
832 }
833
834 impl FromRawSocket for TcpSocket {
835 /// Converts a `RawSocket` to a `TcpStream`.
836 ///
837 /// # Notes
838 ///
839 /// The caller is responsible for ensuring that the socket is in
840 /// non-blocking mode.
841 unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
842 let inner = socket2::Socket::from_raw_socket(socket);
843 TcpSocket { inner }
844 }
845 }
846}
847