Skip to main content

TcpListener

Struct TcpListener 

Source
pub struct TcpListener<M = Local>
where M: Mode,
{ /* private fields */ }
Expand description

A TCP socket server, listening for connections.

Create a listener with TcpListener::bind. Then call accept to take one connection, or incoming for a stream of connections. Each connection is a TcpStream. The listener is the async counterpart of std::net::TcpListener: waiting for a connection lets other tasks run instead of blocking the thread.

The listener runs on the runtime passed to its constructor, and so do the streams it accepts. Its type carries that runtime’s flavour, as the module documentation explains: a TcpListener<Local> (the default) stays on the thread that made it, and a TcpListener<Shared> can be sent to and used from any thread.

Any number of tasks can wait in accept at once through a reference to the listener, and each connection goes to one of them. Only one task at a time can wait for the next item of an Incoming stream, counting all the streams of the listener. Tasks waiting in accept do not count.

§Example

A listener accepts a connection and reads a greeting from it. A client makes the connection and sends the greeting.

use std::net::Ipv4Addr;

use futures::{AsyncReadExt, AsyncWriteExt};
use zruntime::{
    LocalRuntime,
    net::{TcpListener, TcpStream},
};

let runtime = LocalRuntime::new()?;
// Port `0` lets the system pick a free port.
let listener = TcpListener::bind(&runtime, (Ipv4Addr::LOCALHOST, 0))?;
let address = listener.local_addr()?;

runtime.block_on(async {
    let mut client = TcpStream::connect(&runtime, address).await?;
    client.write_all(b"hello").await?;

    let (mut server, peer) = listener.accept().await?;
    let mut greeting = [0; 5];
    server.read_exact(&mut greeting).await?;

    assert_eq!(&greeting, b"hello");
    assert_eq!(peer, client.local_addr()?);
})?;

Implementations§

Source§

impl<M> TcpListener<M>
where M: Mode,

Source

pub fn bind<A>(runtime: &Runtime<M>, addr: A) -> Result<Self>
where A: Into<SocketAddr>,

Creates a listener bound to addr, on runtime.

addr is a socket address: a SocketAddr, or anything that converts into one, such as a pair of an Ipv4Addr and a port. It is never a host name; the module documentation explains what to do instead. Binding to port 0 lets the system pick a free port, which local_addr returns.

The listener is bound and listening when this returns.

§Errors

Fails if the socket cannot be bound to addr, or for the reasons from_std fails.

On wasm32-wasip1 it always fails with Unsupported: that target cannot create a socket (see the module documentation). from_std takes a listener that the host handed in instead.

Source

pub fn from_std(runtime: &Runtime<M>, listener: TcpListener) -> Result<Self>

Creates a listener on runtime from a std listener.

listener is switched to non-blocking mode, as every listener of this type is. On unix, the mode belongs to the open socket, so a duplicate made with try_clone is switched too. An accept on that duplicate then fails with WouldBlock instead of waiting.

§Errors

Fails if switching to non-blocking mode fails, or if the runtime cannot start watching the socket. On Windows a runtime watches a limited number of sockets; see the module documentation.

Source

pub async fn accept(&self) -> Result<(TcpStream<M>, SocketAddr)>

Waits for a connection to this listener, and accepts it.

Returns the stream of the connection and the address of the peer that made it. The stream runs on the listener’s runtime and is in non-blocking mode.

§Errors

Returns the error of the accept.

Some errors leave the connection queued, for example running out of file descriptors (EMFILE) on Linux and the BSDs. The next call then fails again at once, and so on until the connection leaves the queue, so a loop that keeps accepting after an error spins the thread. Back off after an error, for example with Runtime::sleep. On Apple’s platforms an accept that finds no descriptor left closes the connection instead: the error does not repeat, but the connection is lost.

On Windows a runtime watches a limited number of sockets (see the module documentation). An accept that would exceed the limit fails, and the connection it took off the queue is closed. Its peer sees the connection end.

§Cancel safety

Dropping the future before it completes gives up the wait. No connection is lost: a connection that arrives meanwhile stays queued for the next call.

Source

pub fn incoming(&self) -> Incoming<'_, M>

Returns a stream of the connections made to this listener.

Each item is the TcpStream of a connection, accepted as accept accepts it, or the error of a failed accept. See Incoming for how errors and waiting tasks behave.

§Example

The stream yields the first two connections made to a listener, in the order they were made.

use std::net::Ipv4Addr;

use futures::StreamExt;
use zruntime::{
    LocalRuntime,
    net::{TcpListener, TcpStream},
};

let runtime = LocalRuntime::new()?;
let listener = TcpListener::bind(&runtime, (Ipv4Addr::LOCALHOST, 0))?;
let address = listener.local_addr()?;

runtime.block_on(async {
    let first = TcpStream::connect(&runtime, address).await?;
    let second = TcpStream::connect(&runtime, address).await?;

    let mut incoming = listener.incoming();
    let first_accepted = incoming.next().await.expect("the stream never ends")?;
    let second_accepted = incoming.next().await.expect("the stream never ends")?;

    assert_eq!(first_accepted.peer_addr()?, first.local_addr()?);
    assert_eq!(second_accepted.peer_addr()?, second.local_addr()?);
})?;
Source

pub fn local_addr(&self) -> Result<SocketAddr>

The socket address this listener is bound to.

After binding to port 0, this returns the port the system picked.

Source

pub fn ttl(&self) -> Result<u32>

The IP_TTL option of this listener’s socket.

This is the time-to-live field of the IP packets sent from the socket. See set_ttl.

Source

pub fn set_ttl(&self, ttl: u32) -> Result<()>

Sets the IP_TTL option of this listener’s socket.

This is the time-to-live field of the IP packets sent from the socket.

Trait Implementations§

Source§

impl<M> AsFd for TcpListener<M>
where M: Mode,

Available on Unix or WASI only.
Source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
Source§

impl<M> AsRawFd for TcpListener<M>
where M: Mode,

Available on Unix or WASI only.
Source§

fn as_raw_fd(&self) -> RawFd

Extracts the raw file descriptor. Read more
Source§

impl<M> Debug for TcpListener<M>
where M: Mode,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, M> Source<M> for T
where M: Mode, T: AsFd + 'static + IntoSource<M>,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more