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