setsockopt#
Set a kernel-level option on an open socket.
setsockopt is the Perl wrapper around the POSIX setsockopt(2)
system call. It writes the option named by OPTNAME at protocol
LEVEL on the already-opened SOCKET filehandle, using the value
packed into OPTVAL. It is the knob for everything the kernel lets
you tune on a socket — address reuse, keepalives, timeouts, Nagle’s
algorithm, multicast membership, send and receive buffer sizes,
SO_LINGER behaviour on close, and so on. Symbolic names
for LEVEL and OPTNAME come from the Socket
module.
Synopsis#
setsockopt SOCKET, LEVEL, OPTNAME, OPTVAL
What you get back#
A true value on success, undef on failure (with
$! set to the underlying errno: EBADF, ENOPROTOOPT,
EINVAL, ENOTSOCK, etc.). Always check the return value — a
silently-ignored option means the program runs with defaults that
differ from what the code reads:
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
or die "setsockopt SO_REUSEADDR: $!";
Global state it touches#
None directly. setsockopt sets $! on failure; that
is the only interpreter global involved. The effect is on the
kernel-side state of the socket, not on any Perl-level variable.
OPTVAL — packed bytes or a bare integer#
Most socket options take a C int flag. setsockopt accepts either
form for convenience:
A packed byte string whose layout matches the option’s C type, typically built with
pack:pack("l", 1)for a boolean,pack("ll", $on_secs, $on_usecs)for astruct timeval,pack("ii", $on, $linger)forstruct linger.A plain integer, which is shorthand for
pack("i", OPTVAL). Handy forSO_REUSEADDR,TCP_NODELAY, and other boolean flags:setsockopt($sock, IPPROTO_TCP, TCP_NODELAY, 1);
Options whose value is a struct (SO_LINGER, SO_RCVTIMEO,
IP_ADD_MEMBERSHIP) must be passed as an explicit packed
string. A bare integer there produces EINVAL or, worse, silently
writes wrong-sized memory that the kernel misinterprets.
Examples#
Disable Nagle’s algorithm on a TCP socket so small writes go out immediately — useful for latency-sensitive protocols (interactive shells, game traffic, RPC):
use Socket qw(IPPROTO_TCP TCP_NODELAY);
setsockopt($sock, IPPROTO_TCP, TCP_NODELAY, 1)
or die "TCP_NODELAY: $!";
Allow a server to rebind a port that is still in TIME_WAIT from a
previous process — the single most common setsockopt call in
practice, and it must come before bind:
use Socket qw(SOL_SOCKET SO_REUSEADDR);
setsockopt($srv, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
or die "SO_REUSEADDR: $!";
bind($srv, sockaddr_in(9000, INADDR_ANY))
or die "bind: $!";
Set a receive timeout so a blocking recv or read from the
socket returns with EAGAIN / EWOULDBLOCK after 5 seconds instead
of hanging forever. The option value is a packed struct timeval:
use Socket qw(SOL_SOCKET SO_RCVTIMEO);
my $tv = pack("l!l!", 5, 0); # 5 seconds, 0 microseconds
setsockopt($sock, SOL_SOCKET, SO_RCVTIMEO, $tv)
or die "SO_RCVTIMEO: $!";
Enable TCP keepalive probes so half-open connections (peer crashed, cable yanked) are eventually noticed and the socket errors out rather than blocking indefinitely:
use Socket qw(SOL_SOCKET SO_KEEPALIVE);
setsockopt($sock, SOL_SOCKET, SO_KEEPALIVE, 1)
or die "SO_KEEPALIVE: $!";
Make close block for up to 10 seconds while the kernel
flushes unsent data, then discard and reset. SO_LINGER takes a
two-integer struct: the on-flag and the timeout in seconds:
use Socket qw(SOL_SOCKET SO_LINGER);
setsockopt($sock, SOL_SOCKET, SO_LINGER, pack("ii", 1, 10))
or die "SO_LINGER: $!";
Enlarge the kernel receive buffer for a bulk-transfer socket. The
kernel typically doubles the value you request and caps it at
net.core.rmem_max:
use Socket qw(SOL_SOCKET SO_RCVBUF);
setsockopt($sock, SOL_SOCKET, SO_RCVBUF, 1 << 20) # 1 MiB
or die "SO_RCVBUF: $!";
Edge cases#
SOCKETmust already be open.setsockoptdoes not create the socket — callsocketfirst. A closed or never-opened filehandle fails withEBADF.Ordering matters.
SO_REUSEADDRmust be set beforebind.SO_KEEPALIVEcan go before or afterconnect, but for server sockets set it on the accepted child filehandle returned byaccept, not on the listening one — options do not always propagate.Integer shorthand is
pack("i", N), notpack("l", N). On platforms whereintandlongdiffer in size, passing a plain integer and passingpack("l", N)write different byte counts. Both happen to work for the commonint-sized boolean options on LP64 Linux, but the shorthand form is the portable default.Struct-valued options need explicit
pack.SO_LINGER,SO_RCVTIMEO,SO_SNDTIMEO,IP_ADD_MEMBERSHIP,IP_MREQ, and similar take fixed-layout structs. Pass a packed string of the right length or the kernel rejects the call withEINVAL.LEVELpicks the option namespace.SOL_SOCKETfor generic options,IPPROTO_TCPfor TCP-specific (TCP_NODELAY,TCP_KEEPIDLE),IPPROTO_IPfor IPv4 (IP_TTL,IP_ADD_MEMBERSHIP),IPPROTO_IPV6for IPv6. MismatchingLEVELandOPTNAMEgivesENOPROTOOPT.Read-only or unsupported options fail with
ENOPROTOOPT. This also fires when the kernel simply does not know the option — common when copying code between operating systems.Privileged options. A few options (
SO_PRIORITYabove certain values,IP_TRANSPARENT,SO_BINDTODEVICE) requireCAP_NET_ADMINon Linux; an unprivileged call fails withEPERM.Reading back is
getsockopt, notsetsockopt.setsockopthas no query form; usegetsockoptto confirm what the kernel actually stored (it may round, clamp, or double the value).
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
getsockopt— the query counterpart; read back an option to see what the kernel actually appliedsocket— create the socket filehandle thatsetsockoptconfigures; must be called firstbind— setSO_REUSEADDRwithsetsockoptbefore callingbindon a server socketaccept— options set on the listener do not all propagate; re-apply per-connection options on the accepted handlepack— builds theOPTVALbyte string for struct-valued options likeSO_LINGERandSO_RCVTIMEOSocket— source ofSOL_SOCKET,IPPROTO_TCP,SO_REUSEADDR,TCP_NODELAY, and the rest of the symbolic constants