net.tcp: Connections and transfers

TCP Describes the result structure, partial transfer and disconnection responsibilities.

Wave Foundation

Check connection results

std::net::tcp
tcp_connect_addr(addr: SocketAddr) -> NetResult<TcpStream>
tcp_bind_loopback(port: u16) -> NetResult<TcpListener>
tcp_accept(listener: TcpListener) -> NetResult<TcpStream>
tcp_read(stream: TcpStream, buf: ptr<u8>, size: i64) -> i64
tcp_write_all(stream: TcpStream, buf: ptr<u8>, size: i64) -> i64
tcp_read_exact(stream: TcpStream, buf: ptr<u8>, size: i64) -> i64
tcp_close(stream: TcpStream) -> NetError
tcp_close_listener(listener: TcpListener) -> NetError

The link function NetResult<T> has ok, value, and error. Use value only if successful. NetError contains the normalized error classification and native_code, and success can be checked with error.kind == NET_ERROR_NONE. This constant is taken from std::net::error.

The connected stream and the stream received with accept must be closed respectively. Closing a listener does not mean closing all streams it has already accepted. Do not close each copy of the structure.

TCP does not preserve message boundaries

Don't assume that everything you write once will come back to you once you read it. The protocol must be delimited by a length prefix, delimiter, or fixed length. Fixed lengths are handled by tcp_read_exact, and streams of unknown length are handled by read iterations and EOF processing.

Negative numbers are errors, and in positive length reads, 0 is the end of the other end. write_all Some data may have been transmitted before failure. If you retransmit the same content from the beginning, it may be duplicated.

Waiting and time limits

The default blocking function can wait a long time for the other side. For programs that require time restrictions, select the tcp_connect_addr_timeout, tcp_read_timeout, tcp_write_timeout series. Check the millisecond factor and error consequences, and also design a route where the other side does not respond. Asynchronous uses task together with the corresponding asynchronous network API.

address lookup · Completed local client

Criteria for selecting a reading function

action required function value to check
Read some of the arrived data tcp_read Negative error, zero termination, positive number of bytes
Read a certain length tcp_read_exact Has the request length been read in full?
Send given content to the end tcp_write_all Request Length and Return Value
Wait time limit timeout Series Return result and error timeout

For a protocol with a four-byte length field followed by a body, first read the complete length field, check that the length does not exceed the allowed maximum, and then allocate space for the body. Do not allocate large amounts of memory from an unvalidated length supplied by the peer.

When to close the connection

Even if the read function returns 0, local stream resources remain. After finishing reading, call tcp_close. If you use the same cleanup path even after a transmission error, you will not forget to close the normal and failed paths.

A listener is a resource that receives new connections, and a stream is a communication resource that is already connected. When creating a server, you manage both types. Each time accept succeeds, a new stream is created, so we close it after processing it, and close the listener when the server's acceptance iteration is finished.

Try it yourself

Local TCP Client Practice contains the complete code for the server and client. You can distinguish between address lookup and connection failure by comparing cases where the server is run first, when there is no server, and when the port number is different.