accept#
Accept an incoming connection on a listening socket.
accept is the server side of the connection handshake. It waits on
GENERICSOCKET — a socket that has already been created with
socket, bound with bind, and placed in the
listening state with listen — until a client connects,
then installs a brand-new connected socket in NEWSOCKET and returns
the client’s packed address. GENERICSOCKET stays in the listening
state, ready for the next call. Behaviour mirrors the POSIX
accept(2) system call.
Synopsis#
accept NEWSOCKET, GENERICSOCKET
What you get back#
The client’s address in the packed form used by the address family of
GENERICSOCKET — the same shape you’d pass to connect or
unpack with Socket::unpack_sockaddr_in
for IPv4, or with Socket::unpack_sockaddr_in6 / unpack_sockaddr_un
for IPv6 and Unix-domain sockets respectively. On failure returns a
false value (the empty string) and sets $! to the
underlying errno.
NEWSOCKET is populated as a side effect — it is a plain filehandle
argument, not a return value. A bareword like CLIENT autovivifies a
typeglob; a lexical filehandle like my $client is populated in place:
my $client;
accept($client, $server) or die "accept: $!";
# $client is now a readable/writable handle to the connected peer
Global state it touches#
$!— set on failure to the underlyingerrno(EINTR,EAGAIN/EWOULDBLOCKon non-blocking listeners,ECONNABORTED,EMFILE,ENFILE).$^F— the system maximum file descriptor. On systems that support the close-on-exec flag,acceptsetsFD_CLOEXECon the new descriptor when its number is greater than$^F(default2, covering the standard streams). Raise$^Fbeforeacceptif you want the accepted socket to surviveexec.
Examples#
Minimal TCP echo-style accept loop:
use Socket;
socket(my $server, PF_INET, SOCK_STREAM, getprotobyname("tcp"))
or die "socket: $!";
bind($server, sockaddr_in(8080, INADDR_ANY)) or die "bind: $!";
listen($server, SOMAXCONN) or die "listen: $!";
while (my $peer = accept(my $client, $server)) {
my ($port, $iaddr) = sockaddr_in($peer);
print $client "hello ", inet_ntoa($iaddr), ":$port\n";
close $client;
}
die "accept: $!"; # loop exits only on error
Unpack the returned address for logging:
use Socket;
my $peer = accept(my $client, $server)
or die "accept: $!";
my ($port, $iaddr) = sockaddr_in($peer);
printf "connection from %s port %d\n", inet_ntoa($iaddr), $port;
Non-blocking accept. Put $server in non-blocking mode first; a
pending-connection-less call then returns false with $!
set to EAGAIN or EWOULDBLOCK:
use Errno qw(EAGAIN EWOULDBLOCK);
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
my $flags = fcntl($server, F_GETFL, 0);
fcntl($server, F_SETFL, $flags | O_NONBLOCK);
my $peer = accept(my $client, $server);
if (!$peer) {
if ($! == EAGAIN || $! == EWOULDBLOCK) {
# no pending connection — try again later
} else {
die "accept: $!";
}
}
Preserve the accepted socket across exec by raising
$^F so the runtime does not set FD_CLOEXEC:
local $^F = 10_000;
accept(my $client, $server) or die "accept: $!";
exec "/usr/libexec/handler", fileno($client);
Edge cases#
GENERICSOCKETnot listening —acceptfails with$!set toEINVAL. Calllistenon the server socket first.NEWSOCKETalready open — the existing handle is silently closed before the new descriptor is installed, exactly as foropenandsocket. If the old handle was the only reference to a buffered stream, any unflushed data is lost. Close explicitly beforehand when that matters.Signal during the call — a signal delivered while
acceptis blocked makes the underlying syscall returnEINTR. pperl does not auto-restart:acceptreturns false and leaves$!set toEINTR. Wrap in a retry loop if your signal handlers do not terminate the process.Descriptor exhaustion —
EMFILE(process limit) orENFILE(system limit) on a busy server is the common reasonacceptstarts failing under load. Treat them as transient; close idle clients and retry.Address-family mismatch of the packed return value — the packed buffer follows the family of
GENERICSOCKET. Unpacking a Unix-domain address withSocket::unpack_sockaddr_inproduces garbage. Track the family yourself or useSocket::sockaddr_familyto dispatch.Parentheses are optional, commas are not —
accept $c, $sandaccept($c, $s)both work;accept $c $sis a syntax error.List vs scalar context — the packed-address return is a byte string; list context does not expand it into
(port, addr). Callsockaddr_in/ equivalent to unpack.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
socket— create the server socket thatacceptwaits onbind— attach the server socket to a local address beforelistenandacceptlisten— mandatory step betweenbindandaccept; sets the backlog depthconnect— the client-side counterpart;acceptreturns the address aconnectcall suppliedgetpeername— recover the same packed address later fromNEWSOCKETitselfSocket— the constants (PF_INET,SOCK_STREAM,INADDR_ANY) and packers (sockaddr_in,unpack_sockaddr_in) that turn the packed return value into something usable$^F— threshold that controls whetheracceptsetsFD_CLOEXECon the new descriptor