axstd/net/
tcp.rs

1use super::{SocketAddr, ToSocketAddrs};
2use crate::io::{self, prelude::*};
3
4use arceos_api::net::{self as api, AxTcpSocketHandle};
5
6/// A TCP stream between a local and a remote socket.
7pub struct TcpStream(AxTcpSocketHandle);
8
9/// A TCP socket server, listening for connections.
10pub struct TcpListener(AxTcpSocketHandle);
11
12impl TcpStream {
13    /// Opens a TCP connection to a remote host.
14    ///
15    /// `addr` is an address of the remote host. Anything which implements
16    /// [`ToSocketAddrs`] trait can be supplied for the address; see this trait
17    /// documentation for concrete examples.
18    ///
19    /// If `addr` yields multiple addresses, `connect` will be attempted with
20    /// each of the addresses until a connection is successful. If none of
21    /// the addresses result in a successful connection, the error returned from
22    /// the last connection attempt (the last address) is returned.
23    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
24        super::each_addr(addr, |addr: io::Result<&SocketAddr>| {
25            let addr = addr?;
26            let socket = api::ax_tcp_socket();
27            api::ax_tcp_connect(&socket, *addr)?;
28            Ok(TcpStream(socket))
29        })
30    }
31
32    /// Returns the socket address of the local half of this TCP connection.
33    pub fn local_addr(&self) -> io::Result<SocketAddr> {
34        api::ax_tcp_socket_addr(&self.0)
35    }
36
37    /// Returns the socket address of the remote peer of this TCP connection.
38    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
39        api::ax_tcp_peer_addr(&self.0)
40    }
41
42    /// Shuts down the connection.
43    pub fn shutdown(&self) -> io::Result<()> {
44        api::ax_tcp_shutdown(&self.0)
45    }
46}
47
48impl Read for TcpStream {
49    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
50        api::ax_tcp_recv(&self.0, buf)
51    }
52}
53
54impl Write for TcpStream {
55    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
56        api::ax_tcp_send(&self.0, buf)
57    }
58
59    fn flush(&mut self) -> io::Result<()> {
60        Ok(())
61    }
62}
63
64impl TcpListener {
65    /// Creates a new `TcpListener` which will be bound to the specified
66    /// address.
67    ///
68    /// The returned listener is ready for accepting connections.
69    ///
70    /// Binding with a port number of 0 will request that the OS assigns a port
71    /// to this listener. The port allocated can be queried via the
72    /// [`TcpListener::local_addr`] method.
73    ///
74    /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
75    /// its documentation for concrete examples.
76    ///
77    /// If `addr` yields multiple addresses, `bind` will be attempted with
78    /// each of the addresses until one succeeds and returns the listener. If
79    /// none of the addresses succeed in creating a listener, the error returned
80    /// from the last attempt (the last address) is returned.
81    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
82        super::each_addr(addr, |addr: io::Result<&SocketAddr>| {
83            let addr = addr?;
84            let backlog = 128;
85            let socket = api::ax_tcp_socket();
86            api::ax_tcp_bind(&socket, *addr)?;
87            api::ax_tcp_listen(&socket, backlog)?;
88            Ok(TcpListener(socket))
89        })
90    }
91
92    /// Returns the local socket address of this listener.
93    pub fn local_addr(&self) -> io::Result<SocketAddr> {
94        api::ax_tcp_socket_addr(&self.0)
95    }
96
97    /// Accept a new incoming connection from this listener.
98    ///
99    /// This function will block the calling thread until a new TCP connection
100    /// is established. When established, the corresponding [`TcpStream`] and the
101    /// remote peer's address will be returned.
102    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
103        api::ax_tcp_accept(&self.0).map(|(a, b)| (TcpStream(a), b))
104    }
105}