2 use async_std::net::{SocketAddr, TcpListener as AsyncListener, ToSocketAddrs, TcpStream};
3 use async_std::pin::Pin;
4 use async_std::task::{Context, Poll};
5 use async_stream::stream;
7 use futures_lite::StreamExt;
10 /// Listens on a bound socket for incoming TCP connections to be handled as independent
13 /// Implements the [`Stream`] trait to asynchronously accept incoming TCP connections.
20 /// let mut server = TcpListener::bind(ip_address).await?;
22 /// // wait for a connection to come in and be accepted
23 /// while let Some(mut conn) = server.next().await {
24 /// // do something with connection
28 pub struct TcpListener {
29 local_addrs: SocketAddr,
30 // listener: AsyncListener,
31 conn_stream: Pin<Box<dyn Stream<Item = Option<Result<TcpStream, std::io::Error>>> + Send + Sync>>,
35 /// Creates a [`TcpListener`] by binding to an IP address and port and listens for incoming TCP
43 /// let mut server = TcpListener::bind("127.0.0.1:3456").await?;
45 pub async fn bind<A: ToSocketAddrs + std::fmt::Display>(ip_addrs: A) -> anyhow::Result<Self> {
46 let listener = AsyncListener::bind(&ip_addrs).await?;
47 info!("Started TCP server at {}", &ip_addrs);
49 let local_addrs = listener.local_addr()?;
51 let stream = Box::pin(stream! {
53 yield listener.incoming().next().await;
64 // /// Creates a [`Connection`] for the next `accept`ed TCP connection at the bound socket.
71 // /// let mut server = TcpListener::bind("127.0.0.1:3456").await?;
72 // /// while let Ok(mut conn) = server.accept().await? {
73 // /// // handle the connection
76 // pub async fn accept(&self) -> anyhow::Result<Connection> {
77 // let (stream, ip_addr) = self.listener.accept().await?;
78 // debug!("Received connection attempt from {}", ip_addr);
80 // Ok(Connection::from(stream))
84 impl Stream for TcpListener {
85 type Item = Connection;
87 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
88 match self.conn_stream.poll_next(cx) {
89 Poll::Ready(Some(Some(Ok(tcp_stream)))) => {
90 let peer_addr = tcp_stream
92 .expect("Could not retrieve peer IP address");
93 debug!("Received connection attempt from {}", peer_addr);
95 Poll::Ready(Some(Connection::from(tcp_stream)))
98 Poll::Ready(Some(Some(Err(err)))) => {
100 "Encountered error when trying to accept new connection {}",
106 Poll::Ready(Some(None)) => Poll::Ready(None),
108 Poll::Ready(None) => Poll::Ready(None),
110 Poll::Pending => Poll::Pending,