Socket Configuration Options: |
Socket options:
One can "get" (read) the current socket options or "set" them to new values. The default values are obtained from the OS:
-
IPPROTO_IP macro defines are found in /usr/include/netinet/tcp.hLevel Option Type Default Description IPPROTO_IP TCP_NODELAY int 0 Don't delay send to coalesce packets. If set, disable the Nagle algorithm. When not set, data is buffered until there is a sufficient amount to send out, thereby avoiding the frequent sending of small packets, which results in poor utilization of the network. Don't use with TCP_CORK. This option is overridden by TCP_CORK IPPROTO_IP TCP_MAXSEG int 536 Maximum segment size for outgoing TCP packets. TCP will impose its minimum and maximum bounds over the value provided. IPPROTO_IP TCP_CORK int 0 Control sending of partial frames. If set, don't send out partial frames. Not cross platform. IPPROTO_IP TCP_KEEPIDLE int 7200 When the SO_KEEPALIVE option is enabled, TCP probes a connection that has been idle for some amount of time. The default value for this idle period is 2 hours. The TCP_KEEPIDLE option can be used to affect this value for a given socket, and specifies the number of seconds of idle time between keepalive probes.
Not cross platform. This option takes an int value, with a range of 1 to 32767.IPPROTO_IP TCP_KEEPINTVL int 75 Specifies the interval between packets that are sent to validate the connection.
Not cross platform.IPPROTO_IP TCP_KEEPCNT int 9 When the SO_KEEPALIVE option is enabled, TCP probes a connection that has been idle for some amount of time. If the remote system does not respond to a keepalive probe, TCP retransmits the probe a certain number of times before a connection is considered to be broken. The TCP_KEEPCNT option can be used to affect this value for a given socket, and specifies the maximum number of keepalive probes to be sent. This option takes an int value, with a range of 1 to 32767. Not cross platform. IPPROTO_IP TCP_SYNCNT int 5 Number of SYN retransmits that TCP should send before aborting the attempt to connect. It cannot exceed 255. IPPROTO_IP TCP_LINGER2 int 60 Life time of orphaned FIN-WAIT-2 state. Not to be confused with option SO_LINGER
Not cross platform.SOL_SOCKET SO_REUSEADDR int
(bool)0 Allow local address reuse. If a problem is encountered when attempting to bind to a port which has been closed but not released (may take up to 2 minutes as defined by TIME_WAIT). Apply the SO_REUSEADDR socket option to release the resource immediately and to get around the TIME_WAIT state.
0 = disables, 1 = enablesSOL_SOCKET SO_REUSEPORT int
(bool)0 This option is AF_INET socket-specific. This option allows multiple processes to share a port. All incoming multicast or broadcast UDP datagrams that are destined for the port are delivered to all sockets that are bound to the port. All processes that share the port must specify this option.
0 = disables, 1 = enablesSOL_SOCKET SO_ERROR int
(bool)0 When an error occurs on a socket, set error variable so_error and notify process
0 = disables, 1 = enablesSOL_SOCKET SO_BROADCAST int
(bool)0 Permit sending of broadcast datagrams
0 = disables, 1 = enablesSOL_SOCKET SO_SNDBUF int
(value)16384 Send buffer size SOL_SOCKET SO_RCVBUF int
(value)87380 Receive buffer size SOL_SOCKET SO_KEEPALIVE int
(bool)0 Periodically test if connection is alive
0 = disables, 1 = enablesSOL_SOCKET SO_SNDTIMEO timeval
(struct)0
0Set timeout period for socket send.
Disable by setting timeval.tv_sec = 0 sec, timeval.tv_usec = 0 usec (default)
Affects write() writev() send() sendto() and sendmsg()SOL_SOCKET SO_RCVTIMEO timeval
(struct)0
0Set timeout period for socket receive.
Disable by setting timeval.tv_sec = 0 sec, timeval.tv_usec = 0 usec (default)
Affects read() readv() recv() recvfrom() and recvmsg()SOL_SOCKET SO_LINGER linger
(struct)0
0Specifies how close function will operate for connection protocols (TCP)
l_onoff: 0 = disables, 1 = enables
l_linger: 0 = unsent data discarded, 1 = close() does not return untill all unsent data is transmitted or remote connection is closed
Structure defined in sys/socket.hSOL_SOCKET SO_RCVLOWAT int
(value)1 Specifies number of bytes used as a threshold by select() to consider a socket read ready SOL_SOCKET SO_SNDLOWAT int
(value)1 Specifies number of bytes used as a threshold by select() to consider a socket write ready SOL_SOCKET SO_TYPE int
(value)undefined Specifies socket type (e.g., tcp (SOCK_STREAM), udp (SOCK_DGRAM), etc.)
For use with getsockopt() only.
SOL_SOCKET macro defines require /usr/include/sys/socket.hFor a full list of options see the TCP man page
For a full list of IP options see the IP(7) man page
-
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); getsockopt/setsockopt arguments:- int sockfd: Socket file descriptor. Returned by call to "socket".
- int level: See table above
- int optname: See table above
- void *optval: Pointer to value or data structure
- optlen: Length of "optval"
- Returns 0: Sucess, -1: Failure and errno may be set.
Code to read socket options:
-
File:
printSocketOptions.c
Compile: gcc -o printSocketOptions printSocketOptions.c01
#include <sys/socket.h>
02
#include <netinet/in.h>
03
#include <netinet/tcp.h>
04
#include <errno.h>
05
#include <stdio.h>
06
07
int
main()
08
{
09
int
socketHandle;
10
11
// create socket
12
13
if
((socketHandle = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
14
{
15
close(socketHandle);
16
perror
(
"socket"
);
17
}
18
19
int
iSocketOption = 0;
20
int
iSocketOptionLen =
sizeof
(
int
);;
21
22
struct
linger SocketOptionLinger;
23
int
iSocketOptionLingerLen =
sizeof
(
struct
linger);;
24
25
getsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY, (
char
*)&iSocketOption, &iSocketOptionLen);
26
printf
(
"Socket TCP_NODELAY = %d\n"
, iSocketOption);
27
28
getsockopt(socketHandle, IPPROTO_TCP, TCP_MAXSEG, (
char
*)&iSocketOption, &iSocketOptionLen);
29
printf
(
"Socket TCP_MAXSEG = %d\n"
, iSocketOption);
30
31
getsockopt(socketHandle, IPPROTO_TCP, TCP_CORK, (
char
*)&iSocketOption, &iSocketOptionLen);
32
printf
(
"Socket TCP_CORK = %d\n"
, iSocketOption);
33
34
getsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE, (
char
*)&iSocketOption, &iSocketOptionLen);
35
printf
(
"Socket TCP_KEEPIDLE = %d\n"
, iSocketOption);
36
37
getsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL, (
char
*)&iSocketOption, &iSocketOptionLen);
38
printf
(
"Socket TCP_KEEPINTVL = %d\n"
, iSocketOption);
39
40
getsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPCNT, (
char
*)&iSocketOption, &iSocketOptionLen);
41
printf
(
"Socket TCP_KEEPCNT = %d\n"
, iSocketOption);
42
43
getsockopt(socketHandle, IPPROTO_TCP, TCP_SYNCNT, (
char
*)&iSocketOption, &iSocketOptionLen);
44
printf
(
"Socket TCP_SYNCNT = %d\n"
, iSocketOption);
45
46
getsockopt(socketHandle, IPPROTO_TCP, TCP_LINGER2, (
char
*)&iSocketOption, &iSocketOptionLen);
47
printf
(
"Socket TCP_LINGER2 = %d\n"
, iSocketOption);
48
49
getsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, (
char
*)&iSocketOption, &iSocketOptionLen);
50
printf
(
"Socket SO_REUSEADDR = %d\n"
, iSocketOption);
51
52
getsockopt(socketHandle, SOL_SOCKET, SO_ERROR, (
char
*)&iSocketOption, &iSocketOptionLen);
53
printf
(
"Socket SO_ERROR = %d\n"
, iSocketOption);
54
55
getsockopt(socketHandle, SOL_SOCKET, SO_BROADCAST, (
char
*)&iSocketOption, &iSocketOptionLen);
56
printf
(
"Socket SO_BROADCAST = %d\n"
, iSocketOption);
57
58
getsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, (
char
*)&iSocketOption, &iSocketOptionLen);
59
printf
(
"Socket SO_KEEPALIVE = %d\n"
, iSocketOption);
60
61
getsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF, (
char
*)&iSocketOption, &iSocketOptionLen);
62
printf
(
"Socket SO_SNDBUF = %d\n"
, iSocketOption);
63
64
getsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF, (
char
*)&iSocketOption, &iSocketOptionLen);
65
printf
(
"Socket SO_RCVBUF = %d\n"
, iSocketOption);
66
67
getsockopt(socketHandle, SOL_SOCKET, SO_LINGER, (
char
*)&SocketOptionLinger, &iSocketOptionLingerLen);
68
printf
(
"Socket SO_LINGER = %d time = %d\n"
, SocketOptionLinger.l_onoff, SocketOptionLinger.l_linger);
69
70
getsockopt(socketHandle, SOL_SOCKET, SO_RCVLOWAT, (
char
*)&iSocketOption, &iSocketOptionLen);
71
printf
(
"Socket SO_RCVLOWAT = %d\n"
, iSocketOption);
72
}
getsockopt man page: get a particular socket option for the specified socket.
Set socket options:
- Socket "keep-alive":
1
int
iOption = 1;
// Turn on keep-alive, 0 = disables, 1 = enables
2
3
if
(setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE, (
const
char
*) &iOption,
sizeof
(
int
)) == SOCKET_ERROR)
4
{
5
cerr <<
"Set keepalive: Keepalive option failed"
<< endl;
6
}
Set socket client options:
- Socket re-use:
When a socket connection is closed with a call to close(), shutdown() or exit(), both the client and server will send a FIN (final) packet and will then send an acknowledgment (ACK) that they received the packet. The side which initiates the closure will be in a TIME_WAIT state until the process has been completed. This time out period is generally 2-4 minutes in duration. It is hoped that all packets are received in a timely manner and the entire time out duration is not required. When an application is abnormally terminated, the TIME_WAIT period is entered for the full duration.1
int
iOption = 0;
// Reuse address option to set, 0 = disables, 1 = enables
2
3
if
(setsockopt(socketHandle, SOL_SOCKET, SO_REUSEADDR, (
const
char
*) &iOption,
sizeof
(
int
)) == SOCKET_ERROR)
4
{
5
cerr <<
"Set reuse address: Client set reuse address option failed"
<< endl;
6
}
Setting the SO_REUSEADDR option explicitly allows a process to bind a port in the TIME_WAIT state. This is to avoid the error "bind: Address Already in Use". One caviat is that the process can not be to the same address and port as the previous connection. If it is, the SO_REUSEADDR option will not help and the duration of the TIME_WAIT will be in effect.
Solution: Enable socket linger:
For more info see How to avoid the "Address Already in Use" error.
This allows the socket to die quickly and allow the address to be reused again. Warning: This linger configuration specified may/will result in data loss upon socket termination, thus it would not have the robustness required for a banking transaction but would be ok for a recreational app.1
linger Option;
2
Option.l_onoff = 1;
3
Option.l_linger = 0;
4
5
if
(setsockopt(socketHandle, SOL_SOCKET, SO_LINGER, (
const
char
*) &Option,
sizeof
(linger)) == -1)
6
{
7
cerr <<
"Set SO_LINGER option failed"
<< endl;
8
}
- Broadcast:
Struct: remoteSocketInfo.sin_addr.s_addr = htonl(INADDR_BROADCAST);1
int
iOption = 0;
// Broadcast option to set, 0 = disables, 1 = enables
2
3
if
(setsockopt(socketHandle, SOL_SOCKET, SO_BROADCAST, (
const
char
*) &iOption,
sizeof
(
int
)) == SOCKET_ERROR)
4
{
5
cerr <<
"Set reuse address: Client set reuse address option failed"
<< endl;
6
}
setsockopt man page: set a particular socket option for the specified socket.
more info, pls see:http://www.yolinux.com/TUTORIALS/Sockets.html#OPTIONS