cap_std/net/
tcp_stream.rs

1use crate::net::{Shutdown, SocketAddr};
2#[cfg(not(windows))]
3use io_extras::os::rustix::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
4#[cfg(not(windows))]
5use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
6#[cfg(windows)]
7use io_lifetimes::{AsSocket, BorrowedSocket, OwnedSocket};
8use std::io::{self, IoSlice, IoSliceMut, Read, Write};
9use std::time::Duration;
10use std::{fmt, net};
11#[cfg(windows)]
12use {
13    io_extras::os::windows::{
14        AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, IntoRawHandleOrSocket,
15        OwnedHandleOrSocket, RawHandleOrSocket,
16    },
17    std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket},
18};
19
20/// A TCP stream between a local and a remote socket.
21///
22/// This corresponds to [`std::net::TcpStream`].
23///
24/// This `TcpStream` has no `connect` method. To create a `TcpStream`, first
25/// obtain a [`Pool`] permitting the address, and then call
26/// [`Pool::connect_tcp_stream`].
27///
28/// [`Pool`]: struct.Pool.html
29/// [`Pool::connect_tcp_stream`]: struct.Pool.html#method.connect_tcp_stream
30pub struct TcpStream {
31    std: net::TcpStream,
32}
33
34impl TcpStream {
35    /// Constructs a new instance of `Self` from the given
36    /// `std::net::TcpStream`.
37    ///
38    /// This grants access the resources the `std::net::TcpStream` instance
39    /// already has access to.
40    #[inline]
41    pub fn from_std(std: net::TcpStream) -> Self {
42        Self { std }
43    }
44
45    /// Returns the socket address of the remote peer of this TCP connection.
46    ///
47    /// This corresponds to [`std::net::TcpStream::peer_addr`].
48    #[inline]
49    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
50        self.std.peer_addr()
51    }
52
53    /// Returns the local socket address of this listener.
54    ///
55    /// This corresponds to [`std::net::TcpStream::local_addr`].
56    #[inline]
57    pub fn local_addr(&self) -> io::Result<SocketAddr> {
58        self.std.local_addr()
59    }
60
61    /// Shuts down the read, write, or both halves of this connection.
62    ///
63    /// This corresponds to [`std::net::TcpStream::shutdown`].
64    #[inline]
65    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
66        self.std.shutdown(how)
67    }
68
69    /// Creates a new independently owned handle to the underlying socket.
70    ///
71    /// This corresponds to [`std::net::TcpStream::try_clone`].
72    #[inline]
73    pub fn try_clone(&self) -> io::Result<Self> {
74        let tcp_stream = self.std.try_clone()?;
75        Ok(Self::from_std(tcp_stream))
76    }
77
78    /// Sets the read timeout to the timeout specified.
79    ///
80    /// This corresponds to [`std::net::TcpStream::set_read_timeout`].
81    #[inline]
82    pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
83        self.std.set_read_timeout(dur)
84    }
85
86    /// Sets the write timeout to the timeout specified.
87    ///
88    /// This corresponds to [`std::net::TcpStream::set_write_timeout`].
89    #[inline]
90    pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
91        self.std.set_write_timeout(dur)
92    }
93
94    /// Returns the read timeout of this socket.
95    ///
96    /// This corresponds to [`std::net::TcpStream::read_timeout`].
97    #[inline]
98    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
99        self.std.read_timeout()
100    }
101
102    /// Returns the write timeout of this socket.
103    ///
104    /// This corresponds to [`std::net::TcpStream::write_timeout`].
105    #[inline]
106    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
107        self.std.write_timeout()
108    }
109
110    /// Receives data on the socket from the remote address to which it is
111    /// connected, without removing that data from the queue.
112    ///
113    /// This corresponds to [`std::net::TcpStream::peek`].
114    #[inline]
115    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
116        self.std.peek(buf)
117    }
118
119    /// Sets the value of the `TCP_NODELAY` option on this socket.
120    ///
121    /// This corresponds to [`std::net::TcpStream::set_nodelay`].
122    #[inline]
123    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
124        self.std.set_nodelay(nodelay)
125    }
126
127    /// Gets the value of the `TCP_NODELAY` option on this socket.
128    ///
129    /// This corresponds to [`std::net::TcpStream::nodelay`].
130    #[inline]
131    pub fn nodelay(&self) -> io::Result<bool> {
132        self.std.nodelay()
133    }
134
135    /// Sets the value for the `IP_TTL` option on this socket.
136    ///
137    /// This corresponds to [`std::net::TcpStream::set_ttl`].
138    #[inline]
139    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
140        self.std.set_ttl(ttl)
141    }
142
143    /// Gets the value of the `IP_TTL` option for this socket.
144    ///
145    /// This corresponds to [`std::net::TcpStream::ttl`].
146    #[inline]
147    pub fn ttl(&self) -> io::Result<u32> {
148        self.std.ttl()
149    }
150
151    /// Gets the value of the `SO_ERROR` option on this socket.
152    ///
153    /// This corresponds to [`std::net::TcpStream::take_error`].
154    #[inline]
155    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
156        self.std.take_error()
157    }
158
159    /// Moves this TCP stream into or out of nonblocking mode.
160    ///
161    /// This corresponds to [`std::net::TcpStream::set_nonblocking`].
162    #[inline]
163    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
164        self.std.set_nonblocking(nonblocking)
165    }
166}
167
168// Safety: `SocketlikeViewType` is implemented for `std`'s socket types.
169unsafe impl io_lifetimes::views::SocketlikeViewType for TcpStream {}
170
171#[cfg(not(windows))]
172impl FromRawFd for TcpStream {
173    #[inline]
174    unsafe fn from_raw_fd(fd: RawFd) -> Self {
175        Self::from_std(net::TcpStream::from_raw_fd(fd))
176    }
177}
178
179#[cfg(not(windows))]
180impl From<OwnedFd> for TcpStream {
181    #[inline]
182    fn from(fd: OwnedFd) -> Self {
183        Self::from_std(net::TcpStream::from(fd))
184    }
185}
186
187#[cfg(windows)]
188impl FromRawSocket for TcpStream {
189    #[inline]
190    unsafe fn from_raw_socket(socket: RawSocket) -> Self {
191        Self::from_std(net::TcpStream::from_raw_socket(socket))
192    }
193}
194
195#[cfg(windows)]
196impl From<OwnedSocket> for TcpStream {
197    #[inline]
198    fn from(socket: OwnedSocket) -> Self {
199        Self::from_std(net::TcpStream::from(socket))
200    }
201}
202
203#[cfg(not(windows))]
204impl AsRawFd for TcpStream {
205    #[inline]
206    fn as_raw_fd(&self) -> RawFd {
207        self.std.as_raw_fd()
208    }
209}
210
211#[cfg(not(windows))]
212impl AsFd for TcpStream {
213    #[inline]
214    fn as_fd(&self) -> BorrowedFd<'_> {
215        self.std.as_fd()
216    }
217}
218
219#[cfg(windows)]
220impl AsRawSocket for TcpStream {
221    #[inline]
222    fn as_raw_socket(&self) -> RawSocket {
223        self.std.as_raw_socket()
224    }
225}
226
227#[cfg(windows)]
228impl AsSocket for TcpStream {
229    #[inline]
230    fn as_socket(&self) -> BorrowedSocket<'_> {
231        self.std.as_socket()
232    }
233}
234
235#[cfg(windows)]
236impl AsRawHandleOrSocket for TcpStream {
237    #[inline]
238    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
239        self.std.as_raw_handle_or_socket()
240    }
241}
242
243#[cfg(windows)]
244impl AsHandleOrSocket for TcpStream {
245    #[inline]
246    fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
247        self.std.as_handle_or_socket()
248    }
249}
250
251#[cfg(not(windows))]
252impl IntoRawFd for TcpStream {
253    #[inline]
254    fn into_raw_fd(self) -> RawFd {
255        self.std.into_raw_fd()
256    }
257}
258
259#[cfg(not(windows))]
260impl From<TcpStream> for OwnedFd {
261    #[inline]
262    fn from(stream: TcpStream) -> OwnedFd {
263        stream.std.into()
264    }
265}
266
267#[cfg(windows)]
268impl IntoRawSocket for TcpStream {
269    #[inline]
270    fn into_raw_socket(self) -> RawSocket {
271        self.std.into_raw_socket()
272    }
273}
274
275#[cfg(windows)]
276impl From<TcpStream> for OwnedSocket {
277    #[inline]
278    fn from(socket: TcpStream) -> OwnedSocket {
279        socket.std.into()
280    }
281}
282
283#[cfg(windows)]
284impl IntoRawHandleOrSocket for TcpStream {
285    #[inline]
286    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
287        self.std.into_raw_handle_or_socket()
288    }
289}
290
291#[cfg(windows)]
292impl From<TcpStream> for OwnedHandleOrSocket {
293    #[inline]
294    fn from(stream: TcpStream) -> Self {
295        stream.std.into()
296    }
297}
298
299impl Read for TcpStream {
300    #[inline]
301    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
302        self.std.read(buf)
303    }
304
305    #[inline]
306    fn read_vectored(&mut self, bufs: &mut [IoSliceMut]) -> io::Result<usize> {
307        self.std.read_vectored(bufs)
308    }
309
310    #[inline]
311    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
312        self.std.read_exact(buf)
313    }
314
315    #[inline]
316    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
317        self.std.read_to_end(buf)
318    }
319
320    #[inline]
321    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
322        self.std.read_to_string(buf)
323    }
324
325    #[cfg(can_vector)]
326    #[inline]
327    fn is_read_vectored(&self) -> bool {
328        self.std.is_read_vectored()
329    }
330}
331
332impl Read for &TcpStream {
333    #[inline]
334    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
335        (&mut &self.std).read(buf)
336    }
337
338    #[inline]
339    fn read_vectored(&mut self, bufs: &mut [IoSliceMut]) -> io::Result<usize> {
340        (&mut &self.std).read_vectored(bufs)
341    }
342
343    #[inline]
344    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
345        (&mut &self.std).read_exact(buf)
346    }
347
348    #[inline]
349    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
350        (&mut &self.std).read_to_end(buf)
351    }
352
353    #[inline]
354    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
355        (&mut &self.std).read_to_string(buf)
356    }
357
358    #[cfg(can_vector)]
359    #[inline]
360    fn is_read_vectored(&self) -> bool {
361        self.std.is_read_vectored()
362    }
363}
364
365impl Write for TcpStream {
366    #[inline]
367    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
368        self.std.write(buf)
369    }
370
371    #[inline]
372    fn flush(&mut self) -> io::Result<()> {
373        self.std.flush()
374    }
375
376    #[inline]
377    fn write_vectored(&mut self, bufs: &[IoSlice]) -> io::Result<usize> {
378        self.std.write_vectored(bufs)
379    }
380
381    #[inline]
382    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
383        self.std.write_all(buf)
384    }
385
386    #[cfg(can_vector)]
387    #[inline]
388    fn is_write_vectored(&self) -> bool {
389        self.std.is_write_vectored()
390    }
391
392    #[cfg(write_all_vectored)]
393    #[inline]
394    fn write_all_vectored(&mut self, bufs: &mut [IoSlice]) -> io::Result<()> {
395        self.std.write_all_vectored(bufs)
396    }
397}
398
399impl Write for &TcpStream {
400    #[inline]
401    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
402        (&mut &self.std).write(buf)
403    }
404
405    #[inline]
406    fn flush(&mut self) -> io::Result<()> {
407        (&mut &self.std).flush()
408    }
409
410    #[inline]
411    fn write_vectored(&mut self, bufs: &[IoSlice]) -> io::Result<usize> {
412        (&mut &self.std).write_vectored(bufs)
413    }
414
415    #[inline]
416    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
417        (&mut &self.std).write_all(buf)
418    }
419
420    #[cfg(can_vector)]
421    #[inline]
422    fn is_write_vectored(&self) -> bool {
423        self.std.is_write_vectored()
424    }
425
426    #[cfg(write_all_vectored)]
427    #[inline]
428    fn write_all_vectored(&mut self, bufs: &mut [IoSlice]) -> io::Result<()> {
429        (&mut &self.std).write_all_vectored(bufs)
430    }
431}
432
433impl fmt::Debug for TcpStream {
434    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
435        self.std.fmt(f)
436    }
437}