tcp
import std::net::socket::tcp; · source
Types
TcpListener
type struct TcpListener {
fd: i32;
static bind(local: SocketAddr) -> Result<TcpListener, IoError>;
static from_fd(sock: i32) -> TcpListener;
raw_fd(&this) -> i32;
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;
local_addr(&this) -> Result<SocketAddr, IoError>;
}
TcpListener::bind is the one plain call in this file — binding does not wait. Everything else is a future with a start(...) constructor:
import std::net::socket::tcp;
import std::net::addr::socket_addr;
import std::io::buf;
async function serve(addr: SocketAddr) -> Result<(), IoError> {
mut listener: TcpListener = TcpListener::bind(addr)?;
loop {
mut accepted: TcpAccepted = await TcpAccept::start(listener);
listener = accepted.take_listener();
mut conn: BufStream<TcpStream> = BufStream::<TcpStream>::of(accepted.take_result()?);
await handle(conn);
}
}
TcpAccept puts the sockets it produces in non-blocking mode, and the listener closes its descriptor through an inherent drop.
Properties
| Property | Type |
|---|---|
fd | i32 |
Constructors
static bind(local: SocketAddr) -> Result<TcpListener, IoError>;
static bind(local: SocketAddr) -> Result<TcpListener, IoError>;Bind + listen on local (IPv4 or IPv6). Sets SO_REUSEADDR so restarts don't wait out the TIME_WAIT window. Backlog defaults to 128, the same number Linux uses for /proc/sys/net/core/somaxconn these days.
static from_fd(sock: i32) -> TcpListener;
static from_fd(sock: i32) -> TcpListener;Wrap a raw listening descriptor. The caller transfers ownership; drop closes it. Used by TcpAccept to hand the listener back.
Methods
raw_fd(&this) -> i32;
raw_fd(&this) -> i32;Borrow the underlying descriptor without transferring ownership.
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;Put the listener in non-blocking mode, where accept returns WouldBlock instead of sleeping the calling thread. Required before this listener is used with TcpAccept.
local_addr(&this) -> Result<SocketAddr, IoError>;
local_addr(&this) -> Result<SocketAddr, IoError>;The local address the listener is bound to. After bind(.., 0) this reports the kernel-assigned ephemeral port - the only way to learn it (and the hermetic alternative to guessing a fixed port). Handles both v4 and v6 listeners.
TcpStream
type struct TcpStream {
fd: i32;
static from_fd(sock: i32) -> TcpStream;
raw_fd(&this) -> i32;
shutdown_write(mut &this) -> Result<(), IoError>;
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;
}
A connected socket. You get one from TcpConnect or TcpAccept, both of which leave it in non-blocking mode; a stream adopted with from_fd needs set_nonblocking(true) before it is used with a future. shutdown_write half-closes so the peer sees EOF. It closes its descriptor through an inherent drop.
Properties
| Property | Type |
|---|---|
fd | i32 |
Constructors
static from_fd(sock: i32) -> TcpStream;
static from_fd(sock: i32) -> TcpStream;Wrap a raw file descriptor. The caller transfers ownership; drop will close it. Used by TcpAccept to hand over the socket it produced, and to leave a closed placeholder behind when a future takes the real one.
Methods
raw_fd(&this) -> i32;
raw_fd(&this) -> i32;Borrow the underlying file descriptor without transferring ownership. The TcpStream still closes it on drop. Used by net::tls to hand the fd to OpenSSL's socket BIO (which is created BIO_NOCLOSE, so the fd stays this stream's to close).
shutdown_write(mut &this) -> Result<(), IoError>;
shutdown_write(mut &this) -> Result<(), IoError>;Close the write half. Signals "no more from me" without tearing down the read path. Useful for protocols where the client sends then reads to EOF.
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;
set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>;Put the socket in non-blocking mode, where reads and writes report WouldBlock instead of sleeping the calling thread. Required before this stream is used with TcpRead/TcpWrite — a blocking socket would stall an executor's whole worker thread inside the syscall.
The futures
Every operation that can wait is one of these four, each with a start(...) constructor. Each attempts its syscall on the non-blocking socket, and if the socket is not ready registers the polling task's waker with the current Reactor and returns Pending. Registering after the failed attempt is what makes the race safe: the reactor arms level-triggered, so readiness that arrived in between is still reported. These futures park only where a reactor exists — an Executor's worker threads — and polling one anywhere else panics rather than parking a task that could never be woken.
Dropping a future mid-operation releases its reactor registration and, for TcpConnect, closes the half-connected socket — see cancellation is a drop. Only the direction that future owned is cancelled, so a write parked on the same socket keeps waiting.
TcpConnect
type struct TcpConnect {
fd: i32;
addr: [u8;
28];
addrlen: u32;
err: IoError;
rt: Reactor*;
static start(remote: SocketAddr) -> TcpConnect;
}
Completes with Result<TcpStream, IoError>. The socket is opened and the handshake started at construction; each poll asks the OS whether it finished, parking on writability in between.
Properties
| Property | Type |
|---|---|
fd | i32 |
addr | [u8 |
28] | |
addrlen | u32 |
err | IoError |
rt | Reactor* |
Constructors
static start(remote: SocketAddr) -> TcpConnect;
static start(remote: SocketAddr) -> TcpConnect;Open a non-blocking socket and start connecting to remote.
TcpAccept
type struct TcpAccept {
listener: TcpListener;
rt: Reactor*;
static start(listener: TcpListener) -> TcpAccept;
}
Completes with a TcpAccepted: the listener back, plus the new stream or the error.
Properties
| Property | Type |
|---|---|
listener | TcpListener |
rt | Reactor* |
Constructors
static start(listener: TcpListener) -> TcpAccept;
static start(listener: TcpListener) -> TcpAccept;Begin an accept on listener, which this future owns until it completes.
TcpRead
type struct TcpRead {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
static start(stream: TcpStream, buf: Array<u8>) -> TcpRead;
}
Completes with a TcpIo: the stream and buffer back, with outcome() the byte count — 0 at EOF. A read fills buf's [0, length) and truncates it to what arrived, so hand in one sized with resize.
Properties
| Property | Type |
|---|---|
stream | TcpStream |
buf | Array<u8> |
rt | Reactor* |
Constructors
static start(stream: TcpStream, buf: Array<u8>) -> TcpRead;
static start(stream: TcpStream, buf: Array<u8>) -> TcpRead;Begin a read on stream, filling buf — both owned by this future until it completes.
TcpWrite
type struct TcpWrite {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
static start(stream: TcpStream, buf: Array<u8>) -> TcpWrite;
}
Completes with a TcpIo whose outcome() is the bytes accepted, which may be fewer than offered — the caller sends the remainder in another operation.
Properties
| Property | Type |
|---|---|
stream | TcpStream |
buf | Array<u8> |
rt | Reactor* |
Constructors
static start(stream: TcpStream, buf: Array<u8>) -> TcpWrite;
static start(stream: TcpStream, buf: Array<u8>) -> TcpWrite;Begin a write of every byte in buf on stream — both owned by this future until it completes.
The outcomes
type struct TcpIo {
stream: TcpStream;
buf: Array<u8>;
result: Result<u64, IoError>;
take_stream(mut &this) -> TcpStream;
take_buf(mut &this) -> Array<u8>;
outcome(&this) -> Result<u64, IoError>;
}
type struct TcpAccepted {
listener: TcpListener;
result: Result<TcpStream, IoError>;
take_listener(mut &this) -> TcpListener;
take_result(mut &this) -> Result<TcpStream, IoError>;
}
The outputs hand their handles back through take_* rather than by field: a TcpStream closes its descriptor when dropped, so the compiler will not let a field be moved out of an outcome that would still drop it. take_stream swaps in a closed placeholder, leaving nothing behind to close. outcome() is how many bytes moved, or why none did.
TcpIo
Properties
| Property | Type |
|---|---|
stream | TcpStream |
buf | Array<u8> |
result | Result<u64, IoError> |
Methods
take_stream(mut &this) -> TcpStream;
take_stream(mut &this) -> TcpStream;Take the socket back. Calling it twice yields a closed stream the second time — the outcome holds the socket exactly once.
take_buf(mut &this) -> Array<u8>;
take_buf(mut &this) -> Array<u8>;Take the buffer back. After a read it holds exactly the bytes that arrived; after a write it is untouched, so a caller with a short write still has the bytes it has not sent yet. Calling it twice yields an empty buffer the second time.
outcome(&this) -> Result<u64, IoError>;
outcome(&this) -> Result<u64, IoError>;How many bytes moved, or why none did.
TcpAccepted
Properties
| Property | Type |
|---|---|
listener | TcpListener |
result | Result<TcpStream, IoError> |
Methods
take_listener(mut &this) -> TcpListener;
take_listener(mut &this) -> TcpListener;Take the listener back, so the next accept can be started on it.
take_result(mut &this) -> Result<TcpStream, IoError>;
take_result(mut &this) -> Result<TcpStream, IoError>;Take the accepted connection, or the error that prevented one.
Trait implementations
TcpStream
implement trait Drop for struct TcpStream
implement trait AsyncTransport for struct TcpStream
TcpConnect
implement trait Future for struct TcpConnect
implement trait Drop for struct TcpConnect
TcpAccept
implement trait Future for struct TcpAccept
implement trait Drop for struct TcpAccept
TcpRead
implement trait Future for struct TcpRead
implement trait Drop for struct TcpRead
TcpWrite
implement trait Future for struct TcpWrite
implement trait Drop for struct TcpWrite
AsyncTransport is what lets BufStream<TcpStream> exist — its read_into and write_from are TcpRead and TcpWrite with the move-out/move-back handled inside.
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct TcpListener {
fd: i32;
}TcpListener.fd: i32static name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static TcpListener::bind(local: SocketAddr) -> Result<TcpListener, IoError>Bind + listen on local (IPv4 or IPv6). Sets SO_REUSEADDR so restarts don't wait out the TIME_WAIT window. Backlog defaults to 128, the same number Linux uses for /proc/sys/net/core/somaxconn these days.
(parameter) local: SocketAddrtype struct TcpListener {
fd: i32;
}type struct IoError {
kind: IoErrorKind;
os_code: i32;
}static TcpListener::from_fd(sock: i32) -> TcpListenerWrap a raw listening descriptor. The caller transfers ownership; drop closes it. Used by TcpAccept to hand the listener back.
(parameter) sock: i32TcpListener::raw_fd(&this) -> i32Borrow the underlying descriptor without transferring ownership.
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
TcpListener::set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>Put the listener in non-blocking mode, where accept returns WouldBlock instead of sleeping the calling thread. Required before this listener is used with TcpAccept.
mut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
(parameter) on: booleanprimitive ()The unit type: a value that carries no information, and the empty tuple. Distinct from void, which is the absence of a value - Result<(), E> succeeds with nothing to return. 0 bytes.
TcpListener::local_addr(&this) -> Result<SocketAddr, IoError>The local address the listener is bound to. After bind(.., 0) this reports the kernel-assigned ephemeral port - the only way to learn it (and the hermetic alternative to guessing a fixed port). Handles both v4 and v6 listeners.
import a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
async function name(param: Type) -> T { ... }Compiles the function into a stackless state machine. Calling it builds a future whose output is the declared return type; nothing runs until that future is polled. Allowed on free functions, methods, and trait methods.
language referencefunction name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
async function serve(addr: SocketAddr) -> Result<(), IoError>(parameter) addr: SocketAddrmut name: Type = value;A mutable binding, reassignable after declaration - mutability is opt-in, const is the default. At module level it declares mutable global state. Before & it marks an exclusive reference or receiver instead.
mut listener: TcpListenerstatic TcpListener::bind(local: SocketAddr) -> Result<TcpListener, IoError>Bind + listen on local (IPv4 or IPv6). Sets SO_REUSEADDR so restarts don't wait out the TIME_WAIT window. Backlog defaults to 128, the same number Linux uses for /proc/sys/net/core/somaxconn these days.
(parameter) addr: SocketAddrvalue?Error propagation. On a Result<T, E> it yields the T of an Ok and otherwise returns the Err(e) from the enclosing function unchanged; on an Option<T> it yields the T of a Some or returns None. The enclosing function must return a matching Result / Option.
loop { ... }An unconditional loop; it runs until a break (or return) leaves it. Prefer it to while (true): it says outright that the exit is somewhere inside.
mut accepted: TcpAcceptedtype struct TcpAccepted {
listener: TcpListener;
result: Result<TcpStream, IoError>;
}The outcome of an async accept: the listener handed back, plus the connection it produced. Both come out through their take_* methods, for the same reason as TcpIo::take_stream.
await futureSuspends the enclosing async body until the operand - which must implement Future - completes, and evaluates to its output. A prefix operator allowed anywhere an expression is (conditions, arms, guards), but only inside async code.
type struct TcpAccept {
listener: TcpListener;
rt: Reactor*;
}Accept the next incoming connection. An accepted socket does not inherit the listener's non-blocking mode, so it is set here — it is about to be used with these same futures. Owns the listener for the duration and hands it back in the TcpAccepted, so a server loop starts the next accept from that.
static TcpAccept::start(listener: TcpListener) -> TcpAcceptBegin an accept on listener, which this future owns until it completes.
mut listener: TcpListenermut accepted: TcpAcceptedTcpAccepted::take_listener(mut &this) -> TcpListenerTake the listener back, so the next accept can be started on it.
std::net::socket::tcpmut conn: BufStream<TcpStream>type struct BufStream<S> {
inner: S;
rbuf: Array<u8>;
rpos: u64;
scratch: Array<u8>;
wbuf: Array<u8>;
}type struct TcpStream {
fd: i32;
}TcpAccepted::take_result(mut &this) -> Result<TcpStream, IoError>Take the accepted connection, or the error that prevented one.
std::net::socket::tcpmut conn: BufStream<TcpStream>type struct TcpStream {
fd: i32;
}TcpStream.fd: i32static TcpStream::from_fd(sock: i32) -> TcpStreamWrap a raw file descriptor. The caller transfers ownership; drop will close it. Used by TcpAccept to hand over the socket it produced, and to leave a closed placeholder behind when a future takes the real one.
TcpStream::raw_fd(&this) -> i32Borrow the underlying file descriptor without transferring ownership. The TcpStream still closes it on drop. Used by net::tls to hand the fd to OpenSSL's socket BIO (which is created BIO_NOCLOSE, so the fd stays this stream's to close).
TcpStream::shutdown_write(mut &this) -> Result<(), IoError>Close the write half. Signals "no more from me" without tearing down the read path. Useful for protocols where the client sends then reads to EOF.
TcpStream::set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>Put the socket in non-blocking mode, where reads and writes report WouldBlock instead of sleeping the calling thread. Required before this stream is used with TcpRead/TcpWrite — a blocking socket would stall an executor's whole worker thread inside the syscall.
type struct TcpConnect {
fd: i32;
addr: [u8;
28];
addrlen: u32;
err: IoError;
rt: Reactor*;
}Connect to a remote address without blocking. The socket is opened and the handshake started when the future is created; each poll asks the OS whether it finished, parking on writability in between. The socket is closed if the future is dropped before it completes.
TcpConnect.fd: i32TcpConnect.addr: [u8TcpConnect.addrlen: u32TcpConnect.err: IoErrorTcpConnect.rt: Reactor*type struct Reactor {
mtx: [u8;
40];
buckets: [Registration*;
64];
poll_h: i64;
kick_h: i64;
aux_h: i64;
shutdown: Atomic<u8>;
thread: u64;
timers: Timer*;
// … 1 more
}The I/O readiness driver for one Executor. Heap-allocated: worker threads and parked futures hold raw pointers to it, and the backend hands the OS interior addresses, so it must not move.
static TcpConnect::start(remote: SocketAddr) -> TcpConnectOpen a non-blocking socket and start connecting to remote.
(parameter) remote: SocketAddrtype struct TcpConnect {
fd: i32;
addr: [u8;
28];
addrlen: u32;
err: IoError;
rt: Reactor*;
}Connect to a remote address without blocking. The socket is opened and the handshake started when the future is created; each poll asks the OS whether it finished, parking on writability in between. The socket is closed if the future is dropped before it completes.
std::net::socket::tcptype struct TcpAccept {
listener: TcpListener;
rt: Reactor*;
}Accept the next incoming connection. An accepted socket does not inherit the listener's non-blocking mode, so it is set here — it is about to be used with these same futures. Owns the listener for the duration and hands it back in the TcpAccepted, so a server loop starts the next accept from that.
TcpAccept.listener: TcpListenerTcpAccept.rt: Reactor*static TcpAccept::start(listener: TcpListener) -> TcpAcceptBegin an accept on listener, which this future owns until it completes.
(parameter) listener: TcpListenertype struct TcpRead {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Read as soon as the socket has anything to give. Completes with the byte count — 0 means the peer closed its end — or the error that ended it.
TcpRead.stream: TcpStreamTcpRead.buf: Array<u8>type struct Array<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
length: i64;
capacity: i64;
alloc: A;
}Array<T, A>: growable, heap-backed, contiguous sequence.
std::collections::arrayTcpRead.rt: Reactor*static TcpRead::start(stream: TcpStream, buf: Array<u8>) -> TcpReadBegin a read on stream, filling buf — both owned by this future until it completes.
(parameter) stream: TcpStream(parameter) buf: Array<u8>type struct TcpRead {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Read as soon as the socket has anything to give. Completes with the byte count — 0 means the peer closed its end — or the error that ended it.
std::net::socket::tcptype struct TcpWrite {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Write as soon as the socket has room. Completes with the number of bytes accepted, which may be fewer than asked for — a caller with more to send starts another write for the remainder, which is why the buffer comes back untouched. Owns the socket and the buffer exactly as TcpRead does, and for the same reason.
TcpWrite.stream: TcpStreamTcpWrite.buf: Array<u8>TcpWrite.rt: Reactor*static TcpWrite::start(stream: TcpStream, buf: Array<u8>) -> TcpWriteBegin a write of every byte in buf on stream — both owned by this future until it completes.
type struct TcpWrite {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Write as soon as the socket has room. Completes with the number of bytes accepted, which may be fewer than asked for — a caller with more to send starts another write for the remainder, which is why the buffer comes back untouched. Owns the socket and the buffer exactly as TcpRead does, and for the same reason.
type struct TcpIo {
stream: TcpStream;
buf: Array<u8>;
result: Result<u64, IoError>;
}The outcome of an async read/write: the socket handed back, plus how many bytes moved (or why none did).
TcpIo.stream: TcpStreamTcpIo.buf: Array<u8>TcpIo.result: Result<u64, IoError>TcpIo::take_stream(mut &this) -> TcpStreamTake the socket back. Calling it twice yields a closed stream the second time — the outcome holds the socket exactly once.
TcpIo::take_buf(mut &this) -> Array<u8>Take the buffer back. After a read it holds exactly the bytes that arrived; after a write it is untouched, so a caller with a short write still has the bytes it has not sent yet. Calling it twice yields an empty buffer the second time.
TcpIo::outcome(&this) -> Result<u64, IoError>How many bytes moved, or why none did.
type struct TcpAccepted {
listener: TcpListener;
result: Result<TcpStream, IoError>;
}The outcome of an async accept: the listener handed back, plus the connection it produced. Both come out through their take_* methods, for the same reason as TcpIo::take_stream.
TcpAccepted.listener: TcpListenerTcpAccepted.result: Result<TcpStream, IoError>TcpAccepted::take_listener(mut &this) -> TcpListenerTake the listener back, so the next accept can be started on it.
TcpAccepted::take_result(mut &this) -> Result<TcpStream, IoError>Take the accepted connection, or the error that prevented one.
static TcpRead::start(stream: TcpStream, buf: Array<u8>) -> TcpReadBegin a read on stream, filling buf — both owned by this future until it completes.
function name(count: i32, args...)A variadic parameter: the trailing bucket receives any number of further arguments with C's calling convention, so the function stays ABI-compatible with the printf family. Wrap the bucket in VaArgs to read typed values from it.
TcpStream::drop(mut &this) -> voidvia trait Drop
Close both halves. Ownership obligation: every TcpStream must have drop called before going out of scope.
TcpStream.fd: i32static TcpStream::from_fd(sock: i32) -> TcpStreamWrap a raw file descriptor. The caller transfers ownership; drop will close it. Used by TcpAccept to hand over the socket it produced, and to leave a closed placeholder behind when a future takes the real one.
TcpStream::raw_fd(&this) -> i32Borrow the underlying file descriptor without transferring ownership. The TcpStream still closes it on drop. Used by net::tls to hand the fd to OpenSSL's socket BIO (which is created BIO_NOCLOSE, so the fd stays this stream's to close).
TcpStream::set_nonblocking(mut &this, on: boolean) -> Result<(), IoError>Put the socket in non-blocking mode, where reads and writes report WouldBlock instead of sleeping the calling thread. Required before this stream is used with TcpRead/TcpWrite — a blocking socket would stall an executor's whole worker thread inside the syscall.
IoErrorKind::WouldBlockTcpListener::local_addr(&this) -> Result<SocketAddr, IoError>The local address the listener is bound to. After bind(.., 0) this reports the kernel-assigned ephemeral port - the only way to learn it (and the hermetic alternative to guessing a fixed port). Handles both v4 and v6 listeners.
start..endA half-open range - start up to but excluding end - and sugar for Range::new(start, end): an iterator usable in for, and an ordinary value anywhere else. It binds looser than arithmetic, so a..b + 1 is a..(b + 1).
trueThe boolean literal. Booleans are a distinct 1-byte type, not interchangeable with integers; if and while conditions must be boolean.
TcpStream::shutdown_write(mut &this) -> Result<(), IoError>Close the write half. Signals "no more from me" without tearing down the read path. Useful for protocols where the client sends then reads to EOF.
std::net::socket::tcpPoll::Pendingtype struct Executor {
inner: ExecInner*;
worker_tids: [u64];
}A multi-threaded, poll-driven task executor. Construct one, spawn futures onto it (keeping the JoinHandle to await a result, or dropping it to fire-and-forget), and block_on to drive a root future to its value. A pool of worker threads does all polling; the calling thread only ever blocks on a completion condvar.
TcpConnect.addr: [u8TcpConnect.addrlen: u32TcpConnect.err: IoErrorTcpRead.rt: Reactor*TcpAccepted.listener: TcpListenertype struct TcpIo {
stream: TcpStream;
buf: Array<u8>;
result: Result<u64, IoError>;
}The outcome of an async read/write: the socket handed back, plus how many bytes moved (or why none did).
TcpIo::outcome(&this) -> Result<u64, IoError>How many bytes moved, or why none did.
std::net::socket::tcpTcpIo.buf: Array<u8>TcpIo.stream: TcpStreamTcpIo::take_stream(mut &this) -> TcpStreamTake the socket back. Calling it twice yields a closed stream the second time — the outcome holds the socket exactly once.
std::net::socket::tcpTcpIo.result: Result<u64, IoError>TcpIo::take_buf(mut &this) -> Array<u8>Take the buffer back. After a read it holds exactly the bytes that arrived; after a write it is untouched, so a caller with a short write still has the bytes it has not sent yet. Calling it twice yields an empty buffer the second time.
std::net::socket::tcpimplement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referenceimplement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencetype trait AsyncTransport {
async read_into(mut &this, buf: Array<u8>) -> Transfer;
async write_from(mut &this, buf: Array<u8>) -> Transfer;
}One raw, unbuffered async byte channel: what BufStream<S> needs of a transport, and nothing more.
type trait Future {
type Output;
poll(mut &this, cx: Context*) -> Poll<This::Output>;
}An asynchronous computation. poll drives it one step: Ready(v) when the value is available, Pending when it is not yet (the future has arranged, via cx's waker, to be polled again later).
async TcpStream::read_into(mut &this, buf: Array<u8>) -> Transfervia trait AsyncTransport
std::net::socket::tcpasync TcpStream::write_from(mut &this, buf: Array<u8>) -> Transfervia trait AsyncTransport
std::net::socket::tcp