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_frame

  • a complete frame larger than the ordered-byte max_buffer

  • a 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.