IO::As...:Socket(3pm)

πŸ’– IO::Async::Socket πŸ’–

okay so bestie, this is the manual page for IO::Async::Socket β€” a User Contributed Perl Documentation page, no cap. It's all about event callbacks and send buffering for a socket filehandle, and honestly? it ate. Let's get into it 🫢


✨ NAME ✨

"IO::Async::Socket" β€” event callbacks and send buffering for a socket filehandle. that's it, that's the whole vibe πŸ’…


🌸 SYNOPSIS 🌸

here's the whole thing, bestie, verbatim, don't @ me:

use Future::AsyncAwait;
use IO::Async::Socket;

use IO::Async::Loop;
my $loop = IO::Async::Loop->new;

my $socket = IO::Async::Socket->new(
   on_recv => sub {
      my ( $self, $dgram, $addr ) = @_;

      print "Received reply: $dgram\n",
      $loop->stop;
   },
   on_recv_error => sub {
      my ( $self, $errno ) = @_;
      die "Cannot recv - $errno\n";
   },
);
$loop->add( $socket );

await $socket->connect(
   host     => "some.host.here",
   service  => "echo",
   socktype => 'dgram',
);

$socket->send( "A TEST DATAGRAM" );

$loop->run;

πŸ¦‹ DESCRIPTION πŸ¦‹

so this is a subclass of IO::Async::Handle β€” key detail β€” and it wraps up a socket filehandle. it gives you a whole queue of outgoing data. whenever new data shows up from the filehandle it fires the "on_recv" handler. and if you wanna send data to the filehandle, you just call the "send" method. iconic behaviour, truly.

it's primarily meant for "SOCK_DGRAM" or "SOCK_RAW" sockets (think UDP, or packet-capture type situations πŸŽ€). but listen β€” if you've got "SOCK_STREAM" sockets (like TCP, the classic), an instance of IO::Async::Stream is the more appropriate pick. iykyk.


πŸ’œ EVENTS πŸ’œ

these events get invoked either by using subclass methods, or with CODE references in the parameters. choose your fighter ✨

🌈 on_recv $data, $addr

fired the moment a packet, datagram, or stream segment lands.

the "on_recv" handler gets invoked once per packet, datagram, or stream segment that's received. it receives the data itself, plus the sender's address. no more, no less, periodt.

🌸 on_recv_error $errno

optional. fires when the "recv" method on the receiving handle fails. 😭

πŸ“ on_send_error $errno

optional. fires when the "send" method on the sending handle fails.

the "on_recv_error" and "on_send_error" handlers get handed the value of $! from the moment the error happened. and real talk β€” the $! variable itself, by its very nature, may have changed from the original error by the time this handler actually runs, so it should always use the value passed in. always. do not go peeking at $! yourself, bestie πŸ’€

if an error happens and the corresponding error callback was not supplied, and there's no subclass method for it either? then the "close" method gets called instead. that's the fallback, that's the whole plan.

🧚 on_outgoing_empty

optional. fires when the sending data buffer becomes empty. clean vibes ✨


πŸŽ€ PARAMETERS πŸŽ€

you can pass these named parameters to "new" or "configure":

  • read_handle => IO β€” the IO handle to receive from. it must implement "fileno" and "recv" methods. non-negotiable.
  • write_handle => IO β€” the IO handle to send to. it must implement "fileno" and "send" methods.
  • handle => IO β€” shortcut for when you want the same IO handle doing both of the above. one handle, both jobs, main character energy πŸ‘‘
  • on_recv => CODE
  • on_recv_error => CODE
  • on_outgoing_empty => CODE
  • on_send_error => CODE
  • autoflush => BOOL β€” optional. if true, the "send" method will attempt to send data to the operating system immediately, without waiting for the loop to say the filehandle is write-ready. instant gratification fr fr.
  • recv_len => INT β€” optional. sets the buffer size for "recv" calls. defaults to 64 KiB. remember the number πŸ’–
  • recv_all => BOOL β€” optional. if true, it repeatedly calls "recv" when the receiving handle first becomes read-ready. by default this is turned off, meaning at most one fixed-size buffer gets received. if there's still more data sitting in the kernel's buffer, the handle will still be readable, and it'll be received from again.

this behaviour is what lets multiple streams and sockets be multiplexed simultaneously β€” meaning one big bulk transfer can't starve your other filehandles of processing time. turning this option on may improve bulk data transfer rate, but at the risk of delaying or stalling processing on other filehandles. trade-offs, babe 🫢

  • send_all => INT β€” optional. it's the "recv_all" analogue, but for sending. when "autoflush" is enabled, this option only affects deferred sending if the initial attempt failed.
heads up bestie: the condition requiring an "on_recv" handler gets checked at the time the object is added to a Loop. so it is allowed to create an "IO::Async::Socket" object with a read handle but no "on_recv" handler β€” provided that one is later given using "configure" before the stream is added to its containing Loop. and "added" means either directly, or by being a child of another Notifier that's already in a Loop, or added to one. don't skip the configure step, i'm begging πŸ™ˆ

πŸ’… METHODS πŸ’…

✨ send

$socket->send( $data, $flags, $addr );

this method adds a segment of data to be sent β€” or sends it immediately, depending on the "autoflush" parameter. $flags and $addr are both optional.

if the "autoflush" option is set, this method will try immediately to send the data to the underlying filehandle, optionally using the given flags and destination address. if that completes successfully, then congratulations β€” it will have been sent by the time this method returns. slay. but if it fails to send, then the data gets queued as if "autoflush" weren't set at all, and it'll be flushed as normal. no data left behind πŸ’–


🌟 EXAMPLES 🌟

πŸ’Œ Send-first on a UDP Socket

"UDP" is carried by the "SOCK_DGRAM" socket type β€” and for that, the string 'dgram' is a convenient shortcut:

await $socket->connect(
   host     => $hostname,
   service  => $service,
   socktype => 'dgram',
   ...
);

πŸ’Œ Receive-first on a UDP Socket

a typical server pattern with "UDP" involves binding a well-known port number instead of connecting to one, and then just waiting on incoming packets. patient queen behaviour πŸ‘‘

await $socket->bind(
   service  => 12345,
   socktype => 'dgram',
);

πŸ”₯ SEE ALSO πŸ”₯

  • IO::Handle β€” Supply object methods for I/O handles

πŸ‘‘ AUTHOR πŸ‘‘

Paul Evans <leonerd@leonerd.org.uk>


okay and for the cute sign-off: this whole thing is perl v5.40.1, dated 2026-02-21, so if you're reading this from the future β€” hey bestie, hope the sockets are behaving πŸ’–βœ¨πŸ¦‹πŸŒΈπŸŽ€

πŸ“¦ where this page comes from