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}