2 use async_std::net::{SocketAddr, TcpListener, ToSocketAddrs};
3 use async_std::pin::Pin;
4 use futures::task::{Context, Poll};
6 use futures_lite::stream::StreamExt;
10 pub struct TcpServer {
11 local_addrs: SocketAddr,
12 listener: TcpListener,
16 pub async fn new<A: ToSocketAddrs + std::fmt::Display>(ip_addrs: A) -> anyhow::Result<Self> {
17 let listener = TcpListener::bind(&ip_addrs).await?;
18 info!("Started TCP server at {}", &ip_addrs);
21 local_addrs: listener.local_addr()?,
27 impl Stream for TcpServer {
28 type Item = Connection;
30 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
31 match self.listener.incoming().poll_next(cx) {
32 Poll::Pending => Poll::Pending,
34 Poll::Ready(Some(Ok(conn))) => {
36 "Received connection attempt from {}",
38 .expect("Peer address could not be retrieved")
41 Poll::Ready(Some(Connection::from(conn)))
44 Poll::Ready(Some(Err(e))) => {
46 "Encountered error when accepting connection attempt: {}", e
52 Poll::Ready(None) => {
53 info!("Shutting TCP server down at {}", self.local_addrs);