NAME
Linux::Event::Framer::LengthPrefix - Frame messages with a binary payload length
SYNOPSIS
package MessageStream;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
endian => 'big',
max_frame => 1_048_576;
sub on_message ($self, $message) {
say "received " . length($message) . " bytes";
}
DESCRIPTION
Linux::Event::Framer::LengthPrefix is for protocols where every payload is preceded by a fixed-width unsigned binary length.
For example, with:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
endian => 'big';
the payload:
ABC
is sent on the wire as:
00 03 41 42 43
where:
00 03
is the two-byte big-endian integer 3, followed by the three payload bytes.
The encoded number is the payload length.
It does not include the size of the prefix itself.
DECLARING THE FRAMER
A typical declaration is:
package MessageStream;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'LengthPrefix',
bytes => 4,
endian => 'big';
The same framing policy can also be used by ordered-byte Pipe and TTY subclasses.
PREFIX WIDTH
bytes
bytes selects the binary prefix width.
Allowed values are:
1
2
4
The default is:
4
For example:
use Linux::Event::Framer 'LengthPrefix',
bytes => 1;
uses one unsigned byte for the payload length.
PREFIX CAPACITY
The chosen width places a hard mathematical limit on the payload length that can be represented.
The maximum payload lengths are:
bytes => 1 255
bytes => 2 65_535
bytes => 4 4_294_967_295
send rejects a payload larger than the selected prefix can represent.
For example, with:
bytes => 1
this is valid:
$self->send('x' x 255);
but this is not:
$self->send('x' x 256);
This prefix-capacity limit exists even when no max_frame option is supplied.
BYTE ORDER
endian
endian controls byte order for two- and four-byte prefixes.
Allowed values are:
big
little
The default is:
big
For example, the payload length 3 with a two-byte prefix becomes:
big endian: 00 03
little endian: 03 00
A one-byte prefix has no meaningful byte-order difference, but the same option validation still applies.
RECEIVING
Linux::Event first waits until the complete binary prefix is available.
It decodes the payload length, then waits until that many payload bytes are available.
For example, with:
bytes => 2
Linux might receive:
first read: 00
second read: 05 48 45
third read: 4c 4c 4f
Linux::Event still delivers one complete message:
HELLO
The application does not need to preserve partial prefixes or partial payloads itself.
MULTIPLE MESSAGES MAY ARRIVE AT ONCE
One kernel read may contain several complete length-prefixed messages.
For example, a one-byte prefix stream containing:
03foo03bar03baz
produces three messages:
foo
bar
baz
Read boundaries do not affect the protocol boundaries.
ZERO-LENGTH MESSAGES
A payload length of zero is valid.
For example, with a one-byte prefix:
00
represents one empty message.
Likewise:
$self->send('');
produces a zero-length prefix followed by no payload bytes.
The exact prefix width and byte order still follow the class declaration.
INCLUDING THE PREFIX IN INBOUND MESSAGES
include_prefix
By default, on_message receives only the payload:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2;
Wire bytes:
00 03 41 42 43
produce a message containing:
ABC
To include the binary prefix itself in the delivered message:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
include_prefix => 1;
the callback instead receives the complete frame bytes:
00 03 41 42 43
include_prefix affects inbound delivery only.
The prefix is always consumed from the underlying ordered-byte input.
LIMITING PAYLOAD SIZE
max_frame
max_frame provides an application-level payload limit:
use Linux::Event::Framer 'LengthPrefix',
bytes => 4,
max_frame => 1_048_576;
If an inbound prefix declares a payload larger than max_frame, Linux::Event reports a framing error rather than buffering the declared payload.
send also rejects an outbound payload larger than max_frame.
max_frame must be a non-negative integer.
PREFIX CAPACITY AND MAX_FRAME ARE DIFFERENT
There are two independent limits.
For example:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
max_frame => 4096;
has:
protocol capacity: 65_535 bytes
application limit: 4_096 bytes
Even though the two-byte prefix can represent values up to 65,535, this class accepts only payloads of at most 4,096 bytes.
Conversely:
use Linux::Event::Framer 'LengthPrefix',
bytes => 1;
can never send more than 255 payload bytes even without max_frame.
The effective outbound limit is therefore whichever restriction is smaller.
SENDING
send automatically encodes the payload length and prepends it.
For example:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
endian => 'big';
$self->send("abc");
writes:
00 03 61 62 63
The application supplies only the payload.
It should not manually add the length prefix before calling send.
RAW WRITE
write bypasses the framer:
$self->write($bytes);
It writes exactly the supplied bytes.
For example:
$self->write("\x00\x03abc");
can be used when the application intentionally wants direct control over the wire representation.
Normally, send is preferable because it guarantees that the prefix matches the payload length.
INCLUDE_PREFIX DOES NOT CHANGE SENDING
include_prefix controls inbound callback delivery only.
For example:
use Linux::Event::Framer 'LengthPrefix',
bytes => 2,
include_prefix => 1;
still means:
$self->send("abc");
produces:
00 03 61 62 63
send does not expect the application to include the prefix itself.
BYTE LENGTH, NOT CHARACTER COUNT
The prefix describes payload bytes.
Linux::Event therefore calculates the outbound length using byte length.
LengthPrefix framing does not define a character encoding.
If an application wants to send text, it is responsible for encoding that text into the protocol's required byte representation before calling send.
WHEN TO USE LENGTHPREFIX
LengthPrefix is appropriate when the protocol explicitly uses a one-, two-, or four-byte unsigned binary payload length.
It is especially useful for binary protocols where messages may contain any byte value and therefore cannot safely rely on a delimiter.
If every record has one constant size, Fixed is simpler.
If the protocol specifically uses a four-byte network-order length, U32BE is a shorter declaration of the same wire format.
RELATIONSHIP TO U32BE
This declaration:
use Linux::Event::Framer 'LengthPrefix',
bytes => 4,
endian => 'big';
has the same wire representation as:
use Linux::Event::Framer 'U32BE';
U32BE exists as a convenience for that common protocol form.
ERROR BEHAVIOR
An inbound payload length greater than max_frame produces the normal ordered-byte framing error.
Outbound send rejects payloads that exceed either:
the selected prefix capacity
the configured
max_frame
These are application-visible framing failures rather than silent truncation.
PERFORMANCE MODEL
Inbound prefix decoding and frame boundary detection run in Linux::Event's native ordered-byte parser.
Partial prefixes and partial payloads remain in native storage until a complete message is available.
The prefix width and byte order are resolved as immutable class framing policy rather than recalculated as dynamic protocol configuration for every message.
Outbound send calculates the payload byte length, encodes the configured binary prefix, and passes the resulting frame to the ordinary native write path.
SEE ALSO
Linux::Event::Framer, Linux::Event::Framer::U32BE, Linux::Event::Framer::Fixed, Linux::Event::Framer::Delimiter, Linux::Event::IO::Sock::Stream, Linux::Event::IO::Pipe, Linux::Event::IO::TTY, docs/FRAMING.md, docs/CHOOSING-A-FRAMER.md.