Sockets

listen#

Mark a socket as passive so it can accept incoming connections.

listen is the third step in the classic server setup — after socket creates the endpoint and bind fixes it to a local address, listen switches it into the listening state and sizes the kernel’s backlog queue of pending connections. Incoming connections are then drained one at a time with accept. QUEUESIZE is the maximum number of connections the kernel will hold for you before it starts refusing new ones.

Synopsis#

listen SOCKET, QUEUESIZE

What you get back#

True on success, false on failure (with $! set to the errno from the underlying listen(2)). Always check the return value — a server that silently fails to enter the listening state will accept no connections, and the cause (a stale socket file, a port collision, an unbound descriptor) is only visible through $!.

listen $srv, SOMAXCONN
    or die "listen on $path: $!";

Global state it touches#

listen reads no special variables and writes only $! on failure. The call is a thin wrapper over the kernel’s listen(2); effects are on the socket descriptor, not on Perl state.

Examples#

A minimal TCP server. socket, bind, listen, accept in order — miss any step and accept fails:

use Socket;

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

while (accept(my $cli, $srv)) {
    # serve $cli ...
    close $cli;
}

A Unix-domain server. Same sequence, different address family:

use Socket;

my $path = "/tmp/myservice.sock";
unlink $path;                             # stale socket file would cause EADDRINUSE
socket(my $srv, PF_UNIX, SOCK_STREAM, 0)  or die "socket: $!";
bind($srv, sockaddr_un($path))            or die "bind: $!";
listen($srv, 16)                          or die "listen: $!";

Using the POSIX-defined cap SOMAXCONN rather than hard-coding a number. The kernel silently clamps larger values to its own limit anyway; SOMAXCONN documents intent:

use Socket qw(SOMAXCONN);
listen($srv, SOMAXCONN) or die "listen: $!";

A small backlog for a service that processes connections faster than they arrive:

listen($srv, 5) or die "listen: $!";

Re-listening on an already-listening socket. A second call with a different QUEUESIZE is legal on Linux and resizes the backlog in place:

listen($srv, 128) or die "listen: $!";
# ... later, under load:
listen($srv, 1024) or die "listen: $!";   # grow the queue

Edge cases#

  • Call order matters. Calling listen on a socket that has not been bind-ed fails with EDESTADDRREQ (or on some kernels an autobound ephemeral port — do not rely on that). Calling accept before listen fails with EINVAL.

  • Only for connection-oriented sockets. listen is meaningful on SOCK_STREAM and SOCK_SEQPACKET. Calling it on a SOCK_DGRAM socket fails with EOPNOTSUPP; UDP has no notion of pending connections.

  • QUEUESIZE is advisory. The kernel clamps it to /proc/sys/net/core/somaxconn (Linux) regardless of what you ask for. A value of 0 is accepted but means “rely on kernel-default backlog”; it does not disable listening.

  • Negative values are silently treated as 0 by the kernel. Perl does not diagnose this — check your input before passing it to listen.

  • EADDRINUSE at listen vs at bind. Port conflicts for TCP/UDP surface at bind; listen rarely fails with this. For Unix-domain sockets a leftover socket file from a previous run causes bind to fail with EADDRINUSE — remove it with unlink before binding.

  • Stale connections in the queue. When accept runs, the returned connection may already be closed by the peer (the client gave up while queued). Handle that like any other I/O error from the new socket, not as a listen problem.

  • After fork. A listening socket inherited by a child remains listening; both parent and child can accept from the same queue. This is the standard pre-fork server pattern — do not call listen again in the child.

  • SIGPIPE is unrelated. listen itself never raises SIGPIPE; that signal arises on writes to a closed peer after accept.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • socket — creates the endpoint listen will mark as passive; always the first call in the sequence

  • bind — assigns a local address to the socket; must run before listen or the call fails

  • accept — pulls the next pending connection off the backlog queue that listen established

  • setsockopt — set SO_REUSEADDR before bind to avoid TIME_WAIT collisions when restarting a server

  • shutdown — half-close an accepted connection; not used on the listening socket itself

  • $! — holds the errno after a failed listen; the only way to tell EADDRINUSE from EACCES from EOPNOTSUPP