NAME
Linux::Event::IO::Sock::Stream - asynchronous Linux SOCK_STREAM connections
SYNOPSIS
use v5.36;
use Linux::Event::Loop;
use Linux::Event::IO::Sock::Listener;
use Linux::Event::IO::Sock::Stream;
my $loop = Linux::Event::Loop->new;
my $server = Linux::Event::IO::Sock::Listener->new(
loop => $loop,
stream_class => 'Linux::Event::IO::Sock::Stream',
host => '127.0.0.1',
port => 0,
on_data => sub ($stream, $bytes) {
$stream->write($bytes);
},
);
my $prefix = 'received';
my $client = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
host => '127.0.0.1',
port => $server->port,
on_ready => sub ($stream) {
$stream->write('hello');
},
on_data => sub ($stream, $bytes) {
say "$prefix: $bytes";
$stream->close;
$server->close;
$loop->stop;
},
on_error => sub ($stream, $error) {
die "connection failed: $error\n";
},
);
$loop->run;
DESCRIPTION
Linux::Event::IO::Sock::Stream is the public class for connected Linux SOCK_STREAM sockets. TCP over IPv4 or IPv6 and Unix-domain stream sockets use the same class; address family is connection configuration rather than a separate type hierarchy.
The class combines the common ordered-byte engine with socket acquisition, addresses, socket policy, kernel half-close semantics, and optional TLS. A concrete protocol subclass can supply named callbacks and declare class policy; constructor callbacks are an equally supported way to provide application behavior with normal Perl lexical scope.
CALLBACKS, SUBCLASSING, AND TUNING
Constructor callbacks make the public Stream leaf directly useful and preserve ordinary lexical scope. Subclassing remains one of Linux::Event's important distinguishing features because a protocol class can declare, once:
a native Linux::Event::Framer and its wire format;
Linux::Event::TLS identity, verification, ALPN, and role policy;
stream_optionstuning for reads, fairness, batching, buffers, watermarks, limits, and established deadlines; andsocket policy and named, reusable callbacks.
Class policy and method callbacks are validated and cached once per subclass. A constructor callback overrides a same-named method for one connection and is retained once in that object's effective descriptor. This makes it natural to combine reusable high-performance protocol policy with per-connection lexical state without adding event-time method lookup or callback-style selection.
stream_options
Define stream_options as a class method on the Stream subclass. It returns key/value pairs, or one hash reference:
package TunedConnection;
use parent 'Linux::Event::IO::Sock::Stream';
sub stream_options ($class) {
return (
read_size => 131_072,
read_budget_bytes => 524_288,
high_watermark => 2_097_152,
low_watermark => 524_288,
idle_timeout => 60,
);
}
These options also apply to Pipe and TTY subclasses. The complete Stream option set is:
read_size(default 65,536)Maximum bytes requested by one native read; a positive integer.
read_budget_bytes(default 0)Maximum bytes read during one readiness drain. Zero drains until the socket would block.
read_batch_bytes(default 0)For an unframed class, combine successful reads before
on_dataup to this non-negative byte target. Partial batches flush when the current drain ends; zero preserves normal read callback boundaries. It is invalid with framing.message_batch_size(default 0)For a framed class, deliver arrays of at most this many messages to
on_messages. Partial batches flush when the current drain ends; zero useson_message. A positive value requireson_messagesand framing.max_buffer(default 8,388,608)Positive hard byte bound for retained input, an incomplete frame, and the aggregate payload retained for one message batch.
high_watermark(default 1,048,576)Non-negative pending-output byte level at which
writeorsendbegins returning false while still accepting the data.low_watermark(default 262,144)Non-negative pending-output byte level at or below which
on_drainfires after high-watermark backpressure. It must not exceedhigh_watermark.max_pending_bytes(default 0)Hard non-negative pending-output byte limit. Zero means unbounded.
idle_timeout(default 0 seconds)Maximum inactivity interval since successful established input or output progress. Zero disables it.
read_timeout(default 0 seconds)Maximum interval without inbound progress while reading is active. Pausing input suspends it; zero disables it.
write_timeout(default 0 seconds)Maximum interval without output progress while data is queued. Zero disables it.
Byte counts are integers. Timeout values are finite non-negative seconds and may be fractional. Constructor timeout values override class defaults for one Stream; the other values are class policy.
socket_options
Define socket_options as another class method on a Stream subclass. It also returns key/value pairs or one hash reference:
sub socket_options ($class) {
return (
tcp_nodelay => 1,
keepalive => 1,
tcp_user_timeout => 15,
);
}
Unspecified options retain kernel defaults. The complete set is:
tcp_nodelayBoolean
0or1controllingTCP_NODELAY; TCP only.keepaliveBoolean
0or1controllingSO_KEEPALIVE; TCP only.keepalive_idlePositive integer seconds before the first TCP keepalive probe.
keepalive_intervalPositive integer seconds between TCP keepalive probes.
keepalive_countPositive integer number of failed TCP keepalive probes allowed.
tcp_user_timeoutFinite non-negative seconds for
TCP_USER_TIMEOUT; fractional values are rounded up to milliseconds. TCP only.send_bufferPositive integer requested
SO_SNDBUFsize.receive_bufferPositive integer requested
SO_RCVBUFsize.
Positive socket integers are at most 2,147,483,647. Constructor values override class policy for one connection. bind_device is a constructor option, not a socket_options key. configure_socket is the cached cold-path hook for Linux options not covered above.
OUTBOUND CONNECTIONS
connect constructs one connection object whose identity is retained through resolution, connection, optional TLS handshake, established I/O, and close:
my $stream = Client->connect(
loop => $loop, # optional immediate attachment
host => 'example.com', # TCP remote host
port => 443, # TCP remote port
timeout => 10, # connection deadline; default 10
data => $state, # optional application state
);
Use unix => $path for a filesystem Unix-domain stream socket. Advanced callers may supply a packed sockaddr with its numeric family.
loop is optional. Without it, connect returns a detached object that may later be passed to $loop->add($stream). Writes submitted before readiness use the normal bounded output queue and are delivered in order after the transport becomes usable.
Optional source-side controls include numeric local_host, local_port, and bind_device. Hostname resolution is asynchronous and uses the Loop's private native resolver service.
ADOPTED CONNECTED SOCKETS
new(fh => $socket) adopts an already connected SOCK_STREAM handle. The handle is validated, made nonblocking and close-on-exec, and uses the same established I/O path as an accepted or outbound connection. A TLS-declared class must also specify tls_role for an adopted handle because acquisition cannot infer client versus server role.
CALLBACKS
Callbacks may be methods, constructor coderefs, or a mixture:
my $database = ...;
my $stream = RawConnection->new(
fh => $socket,
on_data => sub ($stream, $bytes) {
process_bytes($database, $stream, $bytes);
},
);
A constructor callback overrides the corresponding class method for that object. Supported names and signatures are on_data($stream, $bytes), on_message($stream, $message), on_messages($stream, $messages), on_ready($stream), on_transport_ready($stream), on_drain($stream), on_eof($stream), on_error($stream, $error), and on_close($stream). connect accepts the same callback options as new.
on_ready($stream) runs once when an outbound or accepted connection becomes application-ready. For TLS that means after handshake and verification, not merely after TCP connect. new(fh => ...) adopts a connection that is already ready and does not emit a later readiness callback.
on_transport_ready($stream) is the lower transport notification used by TLS or another native transport and runs immediately before on_ready. Plain connections have no separate transport phase.
A raw object requires on_data($stream, $bytes) as a method or constructor callback. The public Stream leaf can therefore be constructed directly for raw I/O. A framed class uses Linux::Event::Framer and requires on_message or, with explicit batching, on_messages; either may be supplied by the class or constructor.
Optional lifecycle callbacks include on_drain, on_eof, on_error, on_close, and on_transport_ready for transport-specific observation. Method defaults are resolved into an immutable class descriptor. Constructor input callbacks are retained once in native Stream state, producing one effective cached CV with no event-time lookup or method-versus-coderef branch. Lifecycle callbacks are likewise resolved once during construction. Closing or detaching the Stream releases its retained constructor callbacks.
FRAMING AND OUTPUT
write($bytes) sends raw ordered bytes. send($payload) applies the subclass's native framer. The native write engine attempts immediate output, queues only unsent bytes, enables writable readiness only while necessary, and uses high/low watermarks plus optional max_pending_bytes protection.
pause_read and resume_read control application reads. transition_to changes protocol callback/framing descriptors in place while retaining the live socket, transport, output queue, and unread native input according to the transition rules in docs/FRAMING.md.
SOCKET POLICY
A subclass may define socket_options for acquisition-time socket policy. The method shape and complete option contract appear near the top of this document. See docs/SOCKET-CONFIGURATION.md for application order and failure behavior.
ORDERED-BYTE POLICY AND DEADLINES
stream_options has the complete option contract listed near the top of this document. One explicit operation deadline may also be set or changed at runtime. Established timeout policy begins when the application transport is usable; DNS, connect, TLS handshake, and TLS shutdown retain separate lifecycle deadlines.
TLS
A stream-socket subclass opts into TLS declaratively:
package SecureClient;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::TLS
verify => 1,
alpn => ['http/1.1'];
Outbound connect selects client mode and derives the default server name from host. A listener that accepts a TLS-declared class selects server mode; that class must declare cert_file and key_file. Framing and callbacks receive plaintext. See Linux::Event::TLS.
ADDRESSES AND LIFECYCLE
local and peer return lazy Linux::Event::Address values when available. fd, fh, state, pending_bytes, and last_error expose connection state without changing ownership.
end drains accepted output then performs the transport's writable half-close. close is immediate and terminal. detach transfers a plain connected socket only when no output is pending; encrypted transports cannot be detached safely.
SEE ALSO
Linux::Event::IO::Sock::Listener, Linux::Event::IO::Sock::Dgram, Linux::Event::Framer, Linux::Event::TLS, docs/SOCKET-CONNECTIONS.md, docs/ORDERED-BYTE-IO-DESIGN.md, docs/FIRST-CLASS-STREAM-CALLBACKS.md.