Sockets

send#

Send a message on a socket.

send writes the scalar MSG to SOCKET through the operating system’s socket layer, not through PerlIO. On a connected socket (SOCK_STREAM after connect, or an accepted peer) the three-argument form issues a send(2) — use the four-argument form on an unconnected datagram socket (SOCK_DGRAM) to route each message to TO, which triggers sendto(2) under the hood. FLAGS is the bitmask the system call accepts (commonly 0; see your platform’s send(2) man page for MSG_DONTWAIT, MSG_OOB, MSG_NOSIGNAL, and friends).

Synopsis#

send SOCKET, MSG, FLAGS, TO
send SOCKET, MSG, FLAGS

What you get back#

The number of bytes accepted by the kernel, or undef on error with $! set. Always check the return value:

my $n = send $sock, $buf, 0
    or die "send failed: $!";

Two properties bite people:

  • The count is bytes, not characters. length $buf on a wide string and the returned count will not agree.

  • On SOCK_STREAM sockets the kernel may accept fewer bytes than you gave it — a short write. Loop until the whole buffer is drained, or use syswrite which has the same short-write semantics but works on any filehandle.

Global state it touches#

  • $! — set to the system error on failure.

  • The socket’s PerlIO layer stack is not consulted. Output layers (:utf8, :encoding(...), :crlf) have no effect on what send writes. In particular, a :utf8 layer causes send to throw an exception rather than silently encode — the socket layer and the PerlIO layer cannot both own byte framing.

Examples#

Connected TCP — three-argument form:

use Socket;
socket my $sock, PF_INET, SOCK_STREAM, getprotobyname("tcp")
    or die "socket: $!";
connect $sock, sockaddr_in(80, inet_aton("example.com"))
    or die "connect: $!";
send $sock, "GET / HTTP/1.0\r\n\r\n", 0
    or die "send: $!";

Unconnected UDP — four-argument form with an explicit destination:

use Socket;
socket my $sock, PF_INET, SOCK_DGRAM, getprotobyname("udp")
    or die "socket: $!";
my $to = sockaddr_in(514, inet_aton("10.0.0.1"));
send $sock, "<14>hello syslog\n", 0, $to
    or die "send: $!";

Handle short writes on a stream socket:

my $offset = 0;
while ($offset < length $buf) {
    my $n = send $sock, substr($buf, $offset), 0;
    defined $n or die "send: $!";
    $offset += $n;
}

Send with a flag — MSG_DONTWAIT makes a single non-blocking attempt and returns undef with $! set to EAGAIN/EWOULDBLOCK if the kernel buffer is full:

use Socket qw(MSG_DONTWAIT);
my $n = send $sock, $buf, MSG_DONTWAIT;
if (!defined $n) {
    if ($!{EAGAIN} || $!{EWOULDBLOCK}) {
        # back off, retry later
    } else {
        die "send: $!";
    }
}

Edge cases#

  • Wide characters: passing a string with codepoints above 0xFF on a byte socket writes the UTF-8 encoding of each character and emits a Wide character in send warning under use warnings. Encode explicitly with Encode::encode before calling send.

  • :utf8 layer on the socket: send croaks. Either open the socket without the layer, or call binmode $sock to strip it before the first send. An :encoding(...) layer implicitly adds :utf8, so it’s banned too.

  • Four-arg form on a connected socket: passing TO to a connected SOCK_STREAM socket is an error — the kernel returns EISCONN. Use the three-argument form once connected.

  • Three-arg form on an unconnected datagram socket: fails with ENOTCONN (or EDESTADDRREQ on some platforms). Either connect the datagram socket first (which pins a default peer), or supply TO.

  • Empty MSG on UDP: valid — sends a zero-length datagram the peer can read with recv. On TCP it is a no-op that returns 0.

  • SIGPIPE on a closed stream peer: writing to a SOCK_STREAM whose remote end has closed raises SIGPIPE, which by default terminates the process. Pass MSG_NOSIGNAL in FLAGS (Linux) or install $SIG{PIPE} = 'IGNORE' to get an EPIPE return instead.

  • sendmsg(2): Perl exposes send/sendto, not sendmsg. Scatter/gather writes and ancillary data (credentials, file descriptors over AF_UNIX) require an XS module such as Socket::MsgHdr.

  • Non-socket filehandle: send on a non-socket returns undef with $! set to ENOTSOCK. Use syswrite for pipes and regular files.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • recv — the inverse; reads bytes from a socket with the same layer restrictions and the same FLAGS argument

  • syswrite — raw write that bypasses PerlIO buffering on any filehandle; use it for pipes and files where send refuses to work

  • connect — establishes the peer address that lets you use the three-argument form of send

  • socket — creates the filehandle send writes to; the socket type (SOCK_STREAM vs SOCK_DGRAM) decides which form of send is legal

  • bind — assigns a local address; needed before send on a datagram socket if the peer expects replies to a known port

  • binmode — strips a stray :utf8 layer that would otherwise make send throw