mio_st/net/tcp.rs
1use std::io::{self, Read, Write};
2use std::net::{Shutdown, SocketAddr};
3#[cfg(unix)]
4use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
5
6use crate::sys;
7use crate::event::{Evented, EventedId};
8use crate::poll::{Interests, PollOption, Poller};
9
10/// A non-blocking TCP stream between a local socket and a remote socket.
11///
12/// This works much like the `TcpStream` in the standard library, but the
13/// [`Read`] and [`Write`] implementation don't block and instead return a
14/// [`WouldBlock`] error.
15///
16/// [`Read`]: #impl-Read
17/// [`Write`]: #impl-Write
18/// [`WouldBlock`]: https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WouldBlock
19///
20/// # Deregistering
21///
22/// `TcpStream` will deregister itself when dropped.
23///
24/// # Examples
25///
26/// ```
27/// # fn main() -> Result<(), Box<std::error::Error>> {
28/// use mio_st::event::{Events, EventedId};
29/// use mio_st::net::TcpStream;
30/// use mio_st::poll::{Poller, PollOption};
31///
32/// let address = "127.0.0.1:8000".parse()?;
33/// let mut stream = TcpStream::connect(address)?;
34///
35/// let mut poller = Poller::new()?;
36/// let mut events = Events::new();
37///
38/// // Register the socket with `Poller`.
39/// poller.register(&mut stream, EventedId(0), TcpStream::INTERESTS, PollOption::Edge)?;
40///
41/// poller.poll(&mut events, None)?;
42///
43/// // The socket might be ready at this point.
44/// # Ok(())
45/// # }
46/// ```
47#[derive(Debug)]
48pub struct TcpStream {
49 inner: sys::TcpStream,
50}
51
52impl TcpStream {
53 /// The interests to use when registering to receive both readable and
54 /// writable events.
55 pub const INTERESTS: Interests = Interests::BOTH;
56
57 /// Create a new TCP stream and issue a non-blocking connect to the
58 /// specified address.
59 pub fn connect(address: SocketAddr) -> io::Result<TcpStream> {
60 sys::TcpStream::connect(address).map(|inner| TcpStream { inner })
61 }
62
63 /// Returns the socket address of the remote peer of this TCP connection.
64 pub fn peer_addr(&mut self) -> io::Result<SocketAddr> {
65 self.inner.peer_addr()
66 }
67
68 /// Returns the socket address of the local half of this TCP connection.
69 pub fn local_addr(&mut self) -> io::Result<SocketAddr> {
70 self.inner.local_addr()
71 }
72
73 /// Sets the value for the `IP_TTL` option on this socket.
74 pub fn set_ttl(&mut self, ttl: u32) -> io::Result<()> {
75 self.inner.set_ttl(ttl)
76 }
77
78 /// Gets the value of the `IP_TTL` option for this socket.
79 pub fn ttl(&mut self) -> io::Result<u32> {
80 self.inner.ttl()
81 }
82
83 /// Sets the value of the `TCP_NODELAY` option on this socket.
84 pub fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
85 self.inner.set_nodelay(nodelay)
86 }
87
88 /// Gets the value of the `TCP_NODELAY` option on this socket.
89 pub fn nodelay(&mut self) -> io::Result<bool> {
90 self.inner.nodelay()
91 }
92
93 /// Receives data on the socket from the remote address to which it is
94 /// connected, without removing that data from the queue. On success,
95 /// returns the number of bytes peeked.
96 ///
97 /// Successive calls return the same data. This is accomplished by passing
98 /// `MSG_PEEK` as a flag to the underlying recv system call.
99 pub fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
100 self.inner.peek(buf)
101 }
102
103 /// Shuts down the read, write, or both halves of this connection.
104 ///
105 /// This function will cause all pending and future I/O on the specified
106 /// portions to return immediately with an appropriate value (see the
107 /// documentation of [`Shutdown`]).
108 ///
109 /// [`Shutdown`]: https://doc.rust-lang.org/nightly/std/net/enum.Shutdown.html
110 pub fn shutdown(&mut self, how: Shutdown) -> io::Result<()> {
111 self.inner.shutdown(how)
112 }
113
114 /// Get the value of the `SO_ERROR` option on this socket.
115 ///
116 /// This will retrieve the stored error in the underlying socket, clearing
117 /// the field in the process. This can be useful for checking errors between
118 /// calls.
119 pub fn take_error(&mut self) -> io::Result<Option<io::Error>> {
120 self.inner.take_error()
121 }
122}
123
124impl Read for TcpStream {
125 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
126 self.inner.read(buf)
127 }
128}
129
130impl Write for TcpStream {
131 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
132 self.inner.write(buf)
133 }
134
135 fn flush(&mut self) -> io::Result<()> {
136 self.inner.flush()
137 }
138}
139
140impl Evented for TcpStream {
141 fn register(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
142 self.inner.register(poller, id, interests, opt)
143 }
144
145 fn reregister(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
146 self.inner.reregister(poller, id, interests, opt)
147 }
148
149 fn deregister(&mut self, poller: &mut Poller) -> io::Result<()> {
150 self.inner.deregister(poller)
151 }
152}
153
154#[cfg(unix)]
155impl FromRawFd for TcpStream {
156 /// The caller must ensure that the stream is in non-blocking mode when
157 /// using this function.
158 unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
159 TcpStream {
160 inner: FromRawFd::from_raw_fd(fd),
161 }
162 }
163}
164
165#[cfg(unix)]
166impl IntoRawFd for TcpStream {
167 fn into_raw_fd(self) -> RawFd {
168 self.inner.into_raw_fd()
169 }
170}
171
172#[cfg(unix)]
173impl AsRawFd for TcpStream {
174 fn as_raw_fd(&self) -> RawFd {
175 self.inner.as_raw_fd()
176 }
177}
178
179/// A TCP socket listener.
180///
181/// This works much like the `TcpListener` in the standard library, but this
182/// doesn't block when calling [`accept`] and instead returns a [`WouldBlock`]
183/// error.
184///
185/// [`accept`]: #method.accept
186/// [`WouldBlock`]: https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WouldBlock
187///
188/// # Deregistering
189///
190/// `TcpListener` will deregister itself when dropped, **iff** it is not cloned
191/// (via [`try_clone`]).
192///
193/// [`try_clone`]: #method.try_clone
194///
195/// # Examples
196///
197/// ```
198/// # fn main() -> Result<(), Box<std::error::Error>> {
199/// use std::time::Duration;
200///
201/// use mio_st::event::{Events, EventedId};
202/// use mio_st::net::TcpListener;
203/// use mio_st::poll::{Poller, PollOption};
204///
205/// let address = "127.0.0.1:8001".parse()?;
206/// let mut listener = TcpListener::bind(address)?;
207///
208/// let mut poller = Poller::new()?;
209/// let mut events = Events::new();
210///
211/// // Register the socket with `Poller`
212/// poller.register(&mut listener, EventedId(0), TcpListener::INTERESTS, PollOption::Edge)?;
213///
214/// poller.poll(&mut events, Some(Duration::from_millis(100)))?;
215///
216/// // There may be a socket ready to be accepted.
217/// # Ok(())
218/// # }
219/// ```
220#[derive(Debug)]
221pub struct TcpListener {
222 inner: sys::TcpListener,
223}
224
225impl TcpListener {
226 /// The interests to use when registering to receive acceptable connections
227 /// events.
228 pub const INTERESTS: Interests = Interests::READABLE;
229
230 /// Convenience method to bind a new TCP listener to the specified address
231 /// to receive new connections.
232 ///
233 /// This also sets the `SO_REUSEPORT` and `SO_REUSEADDR` options on the
234 /// socket.
235 pub fn bind(address: SocketAddr) -> io::Result<TcpListener> {
236 sys::TcpListener::bind(address).map(|inner| TcpListener { inner })
237 }
238
239 /// Create a independently owned handle to the underlying socket.
240 ///
241 /// The returned `TcpListener` is a reference to the same socket as `self`.
242 /// Both handles can be used to accept incoming connections and options set
243 /// on one listener will affect the other.
244 ///
245 /// # Notes
246 ///
247 /// On Linux when a `TcpListener` is cloned it must deregistered. If its not
248 /// deregistered explicitly and one listener is closed (dropped) and onother
249 /// is still open the poller will still receive events.
250 pub fn try_clone(&self) -> io::Result<TcpListener> {
251 self.inner.try_clone().map(|inner| TcpListener { inner })
252 }
253
254 /// Accepts a new `TcpStream`.
255 ///
256 /// This may return an [`WouldBlock`] error, this means a stream may be
257 /// ready at a later point and one should wait for a notification before
258 /// calling `accept` again.
259 ///
260 /// If an accepted stream is returned, the remote address of the peer is
261 /// returned along with it.
262 ///
263 /// [`WouldBlock`]: https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WouldBlock
264 pub fn accept(&mut self) -> io::Result<(TcpStream, SocketAddr)> {
265 self.inner.accept().map(|(inner, address)| (TcpStream{ inner }, address))
266 }
267
268 /// Returns the local socket address of this listener.
269 pub fn local_addr(&mut self) -> io::Result<SocketAddr> {
270 self.inner.local_addr()
271 }
272
273 /// Sets the value for the `IP_TTL` option on this socket.
274 pub fn set_ttl(&mut self, ttl: u32) -> io::Result<()> {
275 self.inner.set_ttl(ttl)
276 }
277
278 /// Gets the value of the `IP_TTL` option for this socket.
279 pub fn ttl(&mut self) -> io::Result<u32> {
280 self.inner.ttl()
281 }
282
283 /// Get the value of the `SO_ERROR` option on this socket.
284 ///
285 /// This will retrieve the stored error in the underlying socket, clearing
286 /// the field in the process. This can be useful for checking errors between
287 /// calls.
288 pub fn take_error(&mut self) -> io::Result<Option<io::Error>> {
289 self.inner.take_error()
290 }
291}
292
293impl Evented for TcpListener {
294 fn register(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
295 debug_assert!(!interests.is_writable(), "TcpListener only needs readable interests");
296 self.inner.register(poller, id, interests, opt)
297 }
298
299 fn reregister(&mut self, poller: &mut Poller, id: EventedId, interests: Interests, opt: PollOption) -> io::Result<()> {
300 debug_assert!(!interests.is_writable(), "TcpListener only needs readable interests");
301 self.inner.reregister(poller, id, interests, opt)
302 }
303
304 fn deregister(&mut self, poller: &mut Poller) -> io::Result<()> {
305 self.inner.deregister(poller)
306 }
307}
308
309#[cfg(unix)]
310impl FromRawFd for TcpListener {
311 /// The caller must ensure that the listener is in non-blocking mode when
312 /// using this function.
313 unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
314 TcpListener {
315 inner: sys::TcpListener::from_raw_fd(fd),
316 }
317 }
318}
319
320#[cfg(unix)]
321impl IntoRawFd for TcpListener {
322 fn into_raw_fd(self) -> RawFd {
323 self.inner.into_raw_fd()
324 }
325}
326
327#[cfg(unix)]
328impl AsRawFd for TcpListener {
329 fn as_raw_fd(&self) -> RawFd {
330 self.inner.as_raw_fd()
331 }
332}