setsockopt() changes an option on an existing socket. You identify the socket with sockfd, choose the protocol level and optname, point optval at a correctly typed value, and pass its byte count in optlen. Generic options use SOL_SOCKET; TCP-specific options use IPPROTO_TCP. A successful call returns 0; failure returns -1 and sets errno.
Function signature and the five inputs
On Linux, the prototype is:
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
sockfd: a file descriptor returned bysocket(). It must refer to a socket, not an ordinary file.level: the protocol layer that owns the option. UseSOL_SOCKETfor socket-layer options,IPPROTO_TCPfor TCP options, and the relevant IP or IPv6 level for network-layer options.optname: the specific option, such asSO_REUSEADDRorTCP_NODELAY.optval: a pointer to the option value. Many switches use anint, but some options require a structure, string, file descriptor, or protocol-specific buffer.optlen: the number of bytes available atoptval. Passsizeof(value)for an object, not the size of the pointer.
For the common Boolean socket options on Linux, a nonzero integer enables the option and zero disables it. The option’s own manual page defines the required representation and length; do not assume every option accepts an int.
Choosing the protocol level
| Option family | Typical level | Examples | Timing and trade-off | Portability |
|---|---|---|---|---|
| Generic socket behavior | SOL_SOCKET |
SO_REUSEADDR, SO_REUSEPORT, SO_KEEPALIVE, SO_RCVBUF, SO_SNDTIMEO |
Binding, buffering, timeouts, liveness, close behavior, filtering and metadata; timing depends on the individual option | Many are widely available, but exact semantics and names vary by Unix system |
| TCP behavior | IPPROTO_TCP |
TCP_NODELAY, TCP_CORK, TCP_USER_TIMEOUT |
Latency versus batching, congestion behavior, or failure-detection limits | Several are Linux-specific or explicitly non-portable |
| IPv4 or IPv6 behavior | IPPROTO_IP or IPPROTO_IPV6 |
Protocol-specific IP options | Address-family and packet-processing behavior | Check the target platform’s protocol manual |
An option at the wrong level commonly fails with ENOPROTOOPT. The numeric value of an option name is not enough; its owning protocol level is part of the API contract.
Generic SOL_SOCKET examples
Allowing address reuse
int enabled = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
&enabled, sizeof enabled) == -1) {
/* inspect errno */
}
Set this before bind() when the program needs the platform’s SO_REUSEADDR behavior for rebinding. SO_REUSEPORT is a separate option with separate kernel rules; do not treat it as an alias.
#1 Best Overall
Enabling keepalive
int enabled = 1;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
&enabled, sizeof enabled) == -1) {
/* inspect errno */
}
SO_KEEPALIVE enables liveness probing. On Linux, TCP-specific probe intervals and counts are configured separately with TCP_KEEPIDLE, TCP_KEEPINTVL, and TCP_KEEPCNT at IPPROTO_TCP.
Buffers and timeouts
SO_RCVBUF and SO_SNDBUF control socket buffering, affecting memory use and the amount of data that can be in flight. SO_RCVTIMEO and SO_SNDTIMEO use a platform-defined time-value structure rather than a Boolean integer; pass the exact structure and length required by the target system.
Other socket-layer facilities
SO_BROADCASTpermits broadcast transmission where supported.SO_LINGERchanges close behavior and requires a linger structure.SO_ATTACH_FILTERandSO_ATTACH_BPFattach packet filters; classic BPF support is documented from Linux 2.2 and extended BPF attachment from Linux 3.19.SO_ACCEPTCONNis read-only: it reports whetherlisten()has marked the socket as listening, so it is queried withgetsockopt(), not set withsetsockopt().
TCP options at IPPROTO_TCP
TCP_NODELAY: send small segments promptly
int enabled = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
&enabled, sizeof enabled) == -1) {
/* inspect errno */
}
This disables Nagle buffering for the connection, allowing small writes to be sent without that batching delay. It changes a latency-versus-packet-efficiency trade-off; the manual describes the mechanism, not a universal performance improvement.
TCP_CORK: batch partial frames
TCP_CORK holds partial frames so an application can batch writes. Linux documents a 200-millisecond ceiling for the hold. Use it when deliberate aggregation is more important than immediate delivery, and clear it when the batch is complete.
Recommended Free Tools
Rank #3
Keepalive tuning
After enabling SO_KEEPALIVE, Linux TCP exposes TCP_KEEPIDLE, TCP_KEEPINTVL, and TCP_KEEPCNT for idle delay, probe interval, and probe count. These are separate integer options and should be set at IPPROTO_TCP.
Timeout and receive-window controls
TCP_USER_TIMEOUTbounds how long a synchronized connection may remain without successful end-to-end progress. A shorter bound detects failure sooner but tolerates less delay.TCP_WINDOW_CLAMPlimits the advertised receive window.TCP_CONGESTIONselects a per-socket congestion-control algorithm, subject to the algorithms allowed by the system and any required privilege.TCP_DEFER_ACCEPTcontrols when a listening socket is awakened, allowing the listener to wait for more than the initial connection handshake.
Lifecycle: when to set an option
Option timing is option-specific. Binding-related settings such as SO_REUSEADDR are normally applied before bind(). Listener behavior such as TCP_DEFER_ACCEPT belongs on the listening socket before or around listen(), according to the platform’s documentation. Connection behavior such as TCP_NODELAY can be changed on an established TCP socket. When accepted sockets are created, verify whether the desired setting must be applied again to each connected descriptor.
Error handling and diagnosis
Check the return value immediately and preserve errno while reporting the failure:
if (setsockopt(fd, level, name, &value, sizeof value) == -1) {
perror("setsockopt");
}
EBADF:sockfdis not a valid file descriptor.ENOTSOCK: the descriptor is valid but does not refer to a socket.EFAULT:optvalpoints to inaccessible memory.EINVAL: the length, value, or other argument is invalid for that option.ENOPROTOOPT: the option is unknown at the selected protocol level, or unsupported by that protocol.
For a persistent EINVAL, verify the option’s required type, exact optlen, permitted range, socket state, and whether the option is settable rather than read-only. For ENOPROTOOPT, check both the level and the running kernel or operating system; an option documented for Linux may not exist on another Unix system.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Best Value
Portability and privilege
setsockopt() is standardized by POSIX.1-2024 and has roots in POSIX.1-2001, SVr4, 4.4BSD, and 4.2BSD. The portable interface does not make every option portable. Linux’s TCP documentation identifies several options that should not be used in code intended for other systems. Isolate non-portable names behind platform-specific code, test for availability at build time where practical, and provide a fallback behavior.
Some options, including congestion-control selection or packet-filter attachment, can be restricted by system policy or capabilities such as CAP_NET_ADMIN. Treat a successful compile as insufficient evidence that a deployment may set the option.
Quick Recap
A practical checklist
- Confirm that the descriptor is the intended socket and that its address family and type match the option.
- Look up the option under the correct protocol manual and copy its required value type and length.
- Choose the lifecycle point: before
bind(), beforelisten(), beforeconnect(), or after connection establishment. - Pass the object address and
sizeof object; do not pass a pointer size accidentally. - Check for
-1, recorderrno, and distinguish an invalid argument from an unsupported option. - Use
getsockopt()when you need to verify a setting or inspect a read-only status such asSO_ACCEPTCONN. - Test on every target operating system and kernel version when using Linux-specific options.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




