Sockets

socket#

Create a socket filehandle.

socket opens a socket of the kind described by DOMAIN, TYPE, and PROTOCOL and attaches it to SOCKET, which becomes a usable Perl filehandle. It is the thin Perl veneer over the socket(2) system call — nothing more, nothing less. The new socket is unbound and unconnected; you still need bind, connect, or listen+accept to do anything with it. Pull the symbolic constants in with use Socket; before the call — writing the raw integers is portable only by accident.

Synopsis#

use Socket;
socket SOCKET, DOMAIN, TYPE, PROTOCOL

What you get back#

1 on success, undef on failure (with $! set to the errno from the underlying socket(2)). On success SOCKET is now a filehandle you can bind, connect, send / recv on, or read and write with the ordinary I/O operators once it reaches a connected state. The return value is worth checking on every call — a failure here means you have nothing useful to pass to the next socket call, which will then fail in a more confusing way.

socket my $sock, PF_INET, SOCK_STREAM, getprotobyname("tcp")
    or die "socket: $!";

SOCKET can be a bareword filehandle (SOCK), a glob (*SOCK), or an undefined scalar that will be auto-vivified into an anonymous filehandle reference. The auto-vivified form is the modern idiom and the only one that scopes cleanly with my.

Global state it touches#

  • $! — set to the errno from socket(2) on failure.

  • $^F — the system-file-descriptor threshold. On systems with close-on-exec, the new descriptor gets FD_CLOEXEC set when its number exceeds $^F (default 2, so descriptors 0–2 stay inheritable and everything else is auto-closed across exec). Raise it before socket if you specifically want the new socket to survive an exec.

Examples#

A client socket for a TCP connection. Create, connect, talk:

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

A listening TCP server socket. Create, mark reusable, bind, listen:

use Socket;
socket my $srv, PF_INET, SOCK_STREAM, getprotobyname("tcp")
    or die "socket: $!";
setsockopt $srv, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)
    or die "setsockopt: $!";
bind $srv, pack_sockaddr_in(8080, INADDR_ANY) or die "bind: $!";
listen $srv, SOMAXCONN                        or die "listen: $!";

A UDP socket — SOCK_DGRAM instead of SOCK_STREAM, and no connect is needed before send when you pass an explicit destination:

use Socket;
socket my $udp, PF_INET, SOCK_DGRAM, getprotobyname("udp")
    or die "socket: $!";
my $to = pack_sockaddr_in(53, inet_aton("1.1.1.1"));
send $udp, $query, 0, $to or die "send: $!";

A Unix-domain stream socket for local IPC. PF_UNIX with a filesystem path instead of an IP address:

use Socket;
socket my $sock, PF_UNIX, SOCK_STREAM, 0 or die "socket: $!";
connect $sock, pack_sockaddr_un("/run/app.sock") or die "connect: $!";

Letting PROTOCOL default to 0. The kernel picks the default protocol for the domain/type pair — for PF_INET + SOCK_STREAM that is TCP, for PF_INET + SOCK_DGRAM that is UDP. The getprotobyname form above is more explicit but the 0 form is equivalent and avoids one lookup:

use Socket;
socket my $sock, PF_INET, SOCK_STREAM, 0 or die "socket: $!";

Edge cases#

  • use Socket is not optional. Without it, PF_INET, SOCK_STREAM, and friends are bareword strings, not integer constants, and the call fails at the syscall boundary with Invalid argument. The import is what turns them into numbers.

  • SOCKET is clobbered on success. If the slot holds an open filehandle, it is closed first. There is no warning — the previous socket just silently goes away. Use a fresh my variable for each call.

  • Failure leaves SOCKET unchanged. On undef return the scalar is neither opened nor modified; a prior value (including an earlier, still-open socket) is still there.

  • Descriptor limits. socket is the point where EMFILE (per-process) and ENFILE (system-wide) descriptor-table exhaustion shows up. Long-running servers should treat these as recoverable rather than fatal.

  • EAFNOSUPPORT / EPROTONOSUPPORT / ESOCKTNOSUPPORT. The kernel rejected the domain/type/protocol triple. Common cause: asking for PF_INET6 on a kernel built without IPv6, or an invalid protocol number passed through from a stale getprotobyname lookup.

  • Non-blocking mode is a separate step. socket returns a blocking descriptor. Use fcntl with F_SETFL + O_NONBLOCK (or the IO::Socket equivalent) if you need non-blocking I/O.

  • Close-on-exec is automatic past $^F. Perl sets FD_CLOEXEC on the new descriptor when its fd number is greater than $^F. A socket will therefore not survive an exec unless you lowered that threshold or clear the flag with fcntl.

  • Numeric domain/type values are not portable. 2 happens to be AF_INET on Linux; it is something else elsewhere. Always go through the Socket module constants.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • bind — attach a socket created by socket to a local address, required before listen or before sending from a known port

  • connect — initiate an outgoing connection on a SOCK_STREAM socket, or set the default peer on a SOCK_DGRAM socket

  • listen — mark a bound SOCK_STREAM socket as passive so accept can pull connections off it

  • accept — return the next pending connection on a listening socket as a fresh filehandle

  • socketpair — create a connected pair of sockets in one call; the usual choice when both ends live in the same process or parent/child

  • Socket — the module that supplies PF_INET, SOCK_STREAM, inet_aton, pack_sockaddr_in and the rest of the constants and packers you pass to socket

  • $^F — descriptor threshold that controls close-on-exec for the new socket