Connected TCP stream wrapper.
Handle and result model
- Default construction creates an invalid connection handle.
- Connection-creation helpers return a valid connection on success.
makeTcpConnection (address port -- connection result)is the platform factory behindconnectTcp: it connects to the host-order IPv4addressandportand returns the connection with the empty result string on success, or an invalid connection with the failure text. Programs normally callconnectTcp. On Windows, the outgoing socket is put in nonblocking mode, and an immediately successfulConnectExis not itself an error: the completion checks and the connection setup still run.valid?reports only whether the wrapper holds one non-invalid connection handle.- Peer closure is surfaced by read operations, not by
valid?directly. readreturns one transferred byte count together with one result string.readStringreturns one receivedStringtogether with one result string.writeandshutdownreturn one result string only.- The empty result string means success. Any non-empty result string means graceful closure, cancellation, or failure according to the specific operation.
- A valid
TcpConnectionowns one connected stream. Destroying it closes that stream.
Methods
valid?
(-- valid) Reports whether the handle refers to one connection.read
(buffer -- size result) Reads into one Nat8 Span and returns the transferred byte count plus one result string.Preconditions
- The handle is valid.
bufferis oneNat8 Span.
readString
(size -- string result) Reads at most size bytes and returns them as one String plus one result string.Preconditions
- The handle is valid.
write
(source -- result) Writes one source convertible to Nat8 Cref Span and returns one result string.Preconditions
- The handle is valid.
sourceis convertible toNat8 Cref Span.
shutdown
(-- result) Closes the sending side of the connection and returns one result string.Preconditions
- The handle is valid.
Data transfer semantics
readborrows one caller-owned mutableNat8 Spanand writes received bytes into that storage.readStringallocates the returnedStringitself and sizes it to the transferred byte count.writeborrows one source convertible toNat8 Cref Spanand reads bytes from that view without taking ownership.readmay return any positive byte count not greater than the destination span size on success.- A read that transfers no payload bytes is reported as graceful closure through result string
"closed". shutdowncloses only the sending side. The wrapper remains valid and may still report later read-side closure.readandreadStringmay return"canceled"when cancellation is observed before a successful read result is produced.writemay return"canceled"when cancellation is observed before a successful full write result is produced.- Any other non-empty result string is an error description.
- On Linux, a parked read or write also resumes when the socket reports an error or a hangup and then reports its result. On Windows, a read canceled before it resumes consumes no payload bytes; they remain for a later read.
macOS backend
macos/sync/TcpConnectionsetsSO_NOSIGPIPE, makes the socket nonblocking withfcntl, and enablesTCP_NODELAY.- A connection that returns
EINPROGRESSwaits for oneEVFILT_WRITE | EV_ADD | EV_ONESHOTevent and then checksSO_ERROR. - A blocked read waits on one
EVFILT_READ | EV_ADD | EV_ONESHOTevent; a blocked write waits on oneEVFILT_WRITE | EV_ADD | EV_ONESHOTevent. - Cancellation deletes the pending event with
EV_DELETEbefore resuming the corresponding fiber. The public operation result remains"canceled". - Writes retry until the source span is empty or an error or cancellation result is produced; macOS uses
SO_NOSIGPIPErather than LinuxMSG_NOSIGNAL.
Examples
Send bytes and perform one stream read
TCP does not preserve write boundaries. This example performs one read and may print only a prefix of reply; to receive the full five-byte reply, repeat reads until five bytes have been collected.
"String" use
"control" use
"sync/sync" use
{} Int32 {} [
server: [
result: String;
acceptor: 0x7F000001n32 6613n16 listenTcp !result;
[result.size 0 =] "listenTcp failed" ensure
connection: address: @acceptor.accept !result;;
[result.size 0 =] "accept failed" ensure
message: 32 @connection.readString !result;
[result.size 0 =] "readString failed" ensure
"reply" @connection.write !result
[result.size 0 =] "write failed" ensure
];
client: [
result: String;
connection: 0x7F000001n32 6613n16 connectTcp !result;
[result.size 0 =] "connectTcp failed" ensure
"hello" @connection.write !result
[result.size 0 =] "write failed" ensure
message: 32 @connection.readString !result;
[result.size 0 =] "readString failed" ensure
message print
LF print
];
serverContext: @server () spawn;
clientContext: @client () spawn;
@serverContext.wait
@clientContext.wait
0
] "main" exportFunction
Expected Output
reply
See also
- sync/sync: Cross-platform scheduling, sleep, time, IPv4 formatting, and TCP helpers.
- sync/TcpAcceptor: Listening TCP acceptor with address reporting and accepted connection creation.
- windows/TcpConnection: Windows completion-port TCP connection with asynchronous callbacks and cancellation.
- String: UTF-8 string views, owned strings, formatting helpers, and text conversion utilities.
- linux/socket · macos/socket: Linux and macOS socket declarations, constants, address schemas, and imported functions.
- windows/ws2_32: Winsock2 declarations for sockets, overlapped I/O, and address-resolution helpers.