NAME
Linux::Event::Framer::Netstring - Frame messages as canonical netstrings
SYNOPSIS
package NetstringStream;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'Netstring',
max_frame => 1_048_576;
sub on_message ($self, $message) {
say "received: $message";
}
DESCRIPTION
Linux::Event::Framer::Netstring implements canonical netstring framing.
A netstring has this wire form:
length:payload,
For example, the payload:
hello
is represented as:
5:hello,
The decimal number gives the payload length in bytes.
The colon separates the length from the payload.
The comma terminates the complete netstring.
DECLARING THE FRAMER
Declare Netstring after the ordered-byte parent class:
package NetstringStream;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'Netstring';
The same framing policy can also be used with ordered-byte Pipe and TTY subclasses.
RECEIVING
Linux::Event parses the decimal length, waits for exactly that many payload bytes, then requires the trailing comma.
For example, wire input:
5:hello,
delivers:
hello
to on_message.
The framing characters are not included in the delivered payload.
READ BOUNDARIES DO NOT MATTER
A netstring may arrive across several kernel reads.
For example:
first read: 5:h
second read: ell
third read: o,
still produces one complete message:
hello
Linux::Event retains the incomplete netstring until all required bytes are available.
Application code does not need to rebuild the frame manually.
MULTIPLE NETSTRINGS MAY ARRIVE AT ONCE
One read may also contain several complete messages:
3:one,3:two,5:three,
which produces:
one
two
three
Linux::Event continues parsing complete netstrings already available in native input storage.
EMPTY MESSAGES
The canonical representation of an empty payload is:
0:,
Therefore:
$self->send('');
produces exactly:
0:,
and an inbound:
0:,
delivers one empty message.
CANONICAL LENGTH FORMAT
The length field must contain ASCII decimal digits.
For example:
5:hello,
is valid.
A non-digit in the length field is invalid.
The canonical zero representation is:
0
Leading zeroes are not permitted on longer length fields.
For example:
03:abc,
is rejected.
The canonical form is:
3:abc,
This avoids several textual encodings representing the same length.
THE COLON IS REQUIRED
The decimal length must be followed by:
:
For example:
5:hello,
is valid.
A malformed length field that never reaches a colon is not treated as a complete frame.
Invalid characters in that length field cause a framing error.
Linux::Event also bounds the length-field parser so an endlessly growing decimal prefix cannot consume unbounded parser work.
THE TRAILING COMMA IS REQUIRED
After exactly the declared number of payload bytes, the next byte must be:
,
For example:
5:hello,
is valid.
This is not:
5:hello;
and neither is:
5:hello
as a complete netstring.
A wrong terminator produces a framing error.
PAYLOAD CONTENT IS ARBITRARY BYTES
The payload itself can contain any byte values.
It may contain:
:
,
ASCII digits
NUL bytes
binary data
because the length field tells Linux::Event exactly how many bytes belong to the payload.
For example, commas inside the payload do not terminate the netstring early.
Only the comma after the declared payload length is the frame terminator.
LIMITING PAYLOAD SIZE
max_frame
An optional max_frame limits payload size:
use Linux::Event::Framer 'Netstring',
max_frame => 1_048_576;
If an inbound length declares more than max_frame payload bytes, Linux::Event reports a framing error immediately.
It does not wait for the oversized payload to arrive first.
send also rejects outbound payloads larger than max_frame.
max_frame must be a non-negative integer.
MAX_FRAME AND MAX_BUFFER
max_frame limits the netstring payload.
The ordered-byte resource's max_buffer is a separate limit on native input storage.
A complete netstring requires storage for more than just its payload because the decimal length, colon, and trailing comma also occupy bytes.
Linux::Event checks the complete framed size against the ordered-byte buffer limit as well.
SENDING
send generates the canonical netstring automatically.
For example:
$self->send("hello");
writes:
5:hello,
and:
$self->send("ABC");
writes:
3:ABC,
The application supplies only the payload.
Linux::Event calculates the byte length and adds the decimal length, colon, and trailing comma.
RAW WRITE
write bypasses the framer:
$self->write($bytes);
For example:
$self->write("5:hello,");
writes that byte sequence exactly as supplied.
Ordinary Netstring protocol output should normally use send so the declared length and terminator cannot accidentally disagree with the payload.
BYTE LENGTH, NOT CHARACTER COUNT
The decimal number represents payload bytes.
Netstring framing does not define character encoding.
Applications that use Unicode text are responsible for encoding it into the required wire bytes before calling send.
For example, a character whose encoded representation occupies several bytes contributes those several bytes to the netstring length.
MALFORMED INPUT
Linux::Event rejects malformed netstrings rather than guessing what the sender meant.
Examples include:
a non-digit length
a noncanonical leading zero
a decimal length that overflows the supported native integer range
an excessively long length field
a payload larger than
max_framea complete frame larger than the ordered-byte
max_buffera missing or incorrect trailing comma
These conditions use the normal ordered-byte framing error path.
ERROR BEHAVIOR
Malformed or oversized input produces a Linux::Event::Error with type:
framing
The resource then follows its normal framing-error lifecycle.
Linux::Event does not deliver a partial, truncated, or noncanonical netstring as though it were valid.
WHEN TO USE NETSTRING
Netstrings are useful when a protocol wants:
an explicit payload length
arbitrary binary-safe payload contents
a human-readable decimal length
a simple self-delimiting wire format
canonical encoding
If the protocol instead specifies a fixed-width binary length, use Linux::Event::Framer::LengthPrefix or Linux::Event::Framer::U32BE.
PERFORMANCE MODEL
Inbound netstring parsing runs in Linux::Event's native ordered-byte parser.
Decimal-length parsing, canonical-form validation, payload-boundary detection, and trailing-comma validation occur before semantic message delivery crosses into Perl.
Incomplete frames remain in native storage until enough bytes arrive.
Outbound send calculates the payload byte length and creates the canonical:
length:payload,
wire representation before passing it to the ordinary native write path.
SEE ALSO
Linux::Event::Framer, Linux::Event::Framer::LengthPrefix, Linux::Event::Framer::U32BE, Linux::Event::Framer::Varint, Linux::Event::Framer::DecimalLength, Linux::Event::IO::Sock::Stream, Linux::Event::IO::Pipe, Linux::Event::IO::TTY, docs/FRAMING.md, docs/CHOOSING-A-FRAMER.md.