Socket Configuration Options

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:

Level 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 = enables
SOL_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 = enables
SOL_SOCKET SO_ERROR int
(bool)
0 When an error occurs on a socket, set error variable so_error and notify process
0 = disables, 1 = enables
SOL_SOCKET SO_BROADCAST int
(bool)
0 Permit sending of broadcast datagrams
0 = disables, 1 = enables
SOL_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 = enables
SOL_SOCKET SO_SNDTIMEO timeval
(struct)
0
0
Set 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
0
Set 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
0
Specifies 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.h
SOL_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.
IPPROTO_IP macro defines are found in  /usr/include/netinet/tcp.h 
SOL_SOCKET macro defines require  /usr/include/sys/socket.h

For a full list of options see the TCP man page

For a full list of IP options see the IP(7) man page

Function Prototypes:
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
01 #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 }
Compile:  gcc -o printSocketOptions printSocketOptions.c

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:
    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 }
    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.

    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. 
    For more info see How to avoid the "Address Already in Use" error.

    Solution: Enable socket linger:
    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 }
    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.

  • Broadcast:
    view source
    print ?
    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 }
    Struct: remoteSocketInfo.sin_addr.s_addr = htonl(INADDR_BROADCAST);

setsockopt man page: set a particular socket option for the specified socket.



more info, pls see:http://www.yolinux.com/TUTORIALS/Sockets.html#OPTIONS


你可能感兴趣的:(struct,socket,Stream,tcp,protocols,Sockets)