"Linux C" setsockopt detailed

Source: Internet
Author: User
Tags socket error

Transferred from: http://blog.csdn.net/zhonglinzhang/article/details/9183229

Function Description:
Gets or sets the options associated with a socket. Options may exist in multi-tier protocols , and they will always appear on the topmost socket layer. When you manipulate socket options, the options are located at the layer and the name of the option must be given. To manipulate the sockets Layer options, you should specify the value of the layer as sol_socket. The appropriate protocol number for the control option must be given in order to manipulate the other layer's options. For example, to indicate that an option is resolved by the TCP protocol, the layer should be set to protocol number TCP.


Usage:
#include <sys/types.h>
#include <sys/socket.h>

int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);

Parameters:
Sock: The socket that will be set or get the option.
Level: The protocol layer where the option is located.
Optname: The name of the option that needs to be accessed.
Optval: For GetSockOpt (), point to the buffer that returns the value of the option. For setsockopt (), point to the buffer that contains the new option value.
Optlen: For GetSockOpt (), the maximum length of the option value when used as an ingress parameter. The actual length of the option value as an exit parameter. For setsockopt (), the length of the current option.


Return Description:


When executed successfully, returns 0. The failed return -1,errno is set to one of the following values
Ebadf:sock is not a valid file description Word
The memory that Efault:optval points to is not a valid process space
EINVAL: Optlen Invalid when calling setsockopt ()
ENOPROTOOPT: The specified protocol layer does not recognize the option
Enotsock:sock description is not a socket


Parameters Detailed Description:

level specifies the hierarchy of the control sockets. You can take three kinds of values:
1) Sol_socket: Universal socket option.
2) ipproto_ip:ip option.
3) ipproto_tcp:tcp option.
Optname Specify the mode of control (the name of the option), we explain in detail below

Optval Gets or sets the socket option. Conversion based on the data type of the option name


Option Name Description Data type
========================================================================
Sol_socket
------------------------------------------------------------------------
So_broadcast allow sending broadcast data int
So_debug Allow Debug int
So_dontroute do not findRoutingInt
So_error Getting socket error int
So_keepalive remain connected int
So_linger delay closing connection struct LINGER
So_oobinline out-of-band data into normal data stream int
SO_RCVBUF Receive buffer size int
SO_SNDBUF Send buffer size int
So_rcvlowat receive buffer lower bound int
So_sndlowat send buffer lower bound int
So_rcvtimeo Receive timeout struct timeval
So_sndtimeo Send timeout struct timeval
SO_REUSERADDR allow reuse of local addresses and port int
So_type Get socket type int
So_bsdcompat compatible with BSD systems int
========================================================================
Ipproto_ip
------------------------------------------------------------------------
IP_HDRINCL contains the IP header int in the packet
Ip_optinos IP Header option int
Ip_tosServiceType
Ip_ttl Time to live int
========================================================================
Ippro_tcp
------------------------------------------------------------------------
Tcp_maxseg the size of the TCP maximum data segment int
Tcp_nodelay does not use the Nagle algorithm int
========================================================================

So_rcvbuf and So_sndbuf Each set of interfaces has a send buffer and a receive buffer, using these two sets of interface options to change the default buffer size.

Receive buffers
int nrecvbuf=32*1024; Set to 32K
SetSockOpt (S,sol_socket,so_rcvbuf, (const char*) &nrecvbuf,sizeof (int));


Send buffer
int nsendbuf=32*1024;//set to 32K
SetSockOpt (S,sol_socket,so_sndbuf, (const char*) &nsendbuf,sizeof (int));

Attention:

When setting the size of the TCP socket receive buffer, the function call order is important because the TCP window sizing option is used interchangeably with SYN when establishing the connection. For customers, the O_RCVBUF option must be set before connect, and for the server , the SO_RCVBUF option must be set before listen.

Combined with the principle Description:

1. Each set of interfaces has a send buffer and a receive buffer. The receive buffer is used by TCP and UDP to persist the received data to theApplicationProcess to read. TCP:TCP advertises the window size at the other end. The TCP socket receive buffer cannot overflow because the other party is not allowed to emit more data than the advertised window size. This is the traffic control of TCP, and if the other party ignores the window size and emits more data than the window size, the receiver TCP discards it. UDP: This datagram is discarded when the received datagram is not loaded into the socket receive buffer. UDP is no traffic control, the fast sender can easily drown the slow receiver, causing the receiver's UDP drop datagram.
2. We often hear about the three handshake of the TCP protocol, but what are the details of the three handshake, and why do we do it?
The first time: The client sends the connection request to the server, the server receives;
Second time: The server returns a confirmation code to the client, with a connection request from the server to the client, the client receives, and confirms the client-to-server connection.
Third time: The client returns the confirmation code of the last request sent by the server, the server receives it, and confirms the server-to-client connection.
We can see:
1. Each connection to TCP needs to be confirmed.
2. Client-to-server and server-to-client connections are independent.
Let's think about the characteristics of the TCP protocol: connected, reliable, full-duplex, and actually TCP's three-time handshake is just to ensure that these features are implemented.


Usage of 3.setsockopt

1.closesocket (typically does not close immediately and undergoes the time_wait process) to continue to reuse the socket:
BOOL breuseaddr=true;
SetSockOpt (S,sol_socket, SO_REUSEADDR, (const char*) &breuseaddr,sizeof (BOOL));


2. If you want a soket that is already in the connected state to be forced to close after calling Closesocket, do not experience the TIME_WAIT process:
BOOL Bdontlinger = FALSE;
SetSockOpt (S,sol_socket,so_dontlinger, (const char*) &bdontlinger,sizeof (BOOL));


3. In the Send (), recv () process sometimes due to network conditions and other reasons, the collection can not be expected to proceed, and set the time and delivery period:
int NNETTIMEOUT=1000;//1 sec
Delivery time limit
SetSockOpt (Socket,sol_s0cket,so_sndtimeo, (char *) &nnettimeout,sizeof (int));
Receiving time limit
SetSockOpt (Socket,sol_s0cket,so_rcvtimeo, (char *) &nnettimeout,sizeof (int));


4. In Send (), the actual bytes sent (synchronous) or bytes sent to the socket buffer are returned.
(asynchronous); The system default state send and Receive is 8688 bytes (approximately 8.5K), and data is sent in the actual process.
and receive a large amount of data, you can set the socket buffer, and avoid the Send (), recv () Continuous loop transceiver:
Receive buffers
int nrecvbuf=32*1024;//set to 32K
SetSockOpt (S,sol_socket,so_rcvbuf, (const char*) &nrecvbuf,sizeof (int));
Send buffer
int nsendbuf=32*1024;//set to 32K
SetSockOpt (S,sol_socket,so_sndbuf, (const char*) &nsendbuf,sizeof (int));


5. If you do not want to experience a copy of the system buffer to the socket buffer when sending the data
Performance of the program:
int nzero=0;
SetSockOpt (Socket,sol_s0cket,so_sndbuf, (char *) &nzero,sizeof (Nzero));


6. Complete the above function (by default, copy the contents of the socket buffer to the system buffer) in recv ():
int nzero=0;
SetSockOpt (Socket,sol_s0cket,so_rcvbuf, (char *) &nzero,sizeof (int));


7. In general, when sending a UDP datagram, you want the data sent by the socket to have broadcast characteristics:
BOOL bbroadcast=true;
SetSockOpt (S,sol_socket,so_broadcast, (const char*) &bbroadcast,sizeof (BOOL));


8. In the Client connection server process, if the socket in nonblocking mode can set the Connect () delay in the process of connect () until Accpet () is called (This function setting has a significant effect in the non-blocking process, Not very useful in blocking function calls)
BOOL bconditionalaccept=true;
SetSockOpt (s,sol_socket,so_conditional_accept, (const char*) &bconditionalaccept,sizeof (BOOL));


9. If in the process of sending the data (send () is not completed, and the data is not sent) and call Closesocket (), previously we generally take the measure is "calmly close" shutdown (S,sd_both), but the data is definitely lost, How do I set up a program that meets the requirements of a specific application (that is, after sending out data that has not been sent out and closing the socket)?
struct Linger {
U_short L_onoff;
U_short L_linger;
};
Linger M_slinger;
m_slinger.l_onoff=1;//(in the closesocket () call, but there is no data sent when the time allowed to stay)
If m_slinger.l_onoff=0, then function and 2.) function the same;
m_slinger.l_linger=5;//(allow 5 seconds to stay)
SetSockOpt (S,sol_socket,so_linger, (const char*) &m_slinger,sizeof (LINGER));

Note: Options for two sets of interfaces: One is a Boolean option that allows or disables one, and the other is an reshape or structure option. Allows a boolean option to point optval to a non-0-shaped number; Disables an option optval points to an integer equal to zero. For Boolean options, Optlen should be equal to sizeof (int), and for other options, optval points to the number of shapes or structures that contain the desired options, while Optlen is the number of shapes or the length of the structure. The So_linger option is used to control actions that have queued pending data on the socket interface and that the closesocket () call has been executed. See the Closesocket () function for the effect of the So_linger option on closesocket () semantics. The application sets the appropriate operation characteristics by creating a linger structure:
   struct linger {
int l_onoff;
int L_linger;
   };
    to allow So_linger, the application should set L_onoff to nonzero, set L_linger to zero or the required time-out value (in seconds), and then call SetSockOpt (). In order to allow So_dontlinger (that is, prohibit so_linger), L_onoff should be set to zero and then call setsockopt ().
    By default, a set of interfaces cannot be bundled with a local address that is already in use (see Bind ()). Sometimes, however, a "reuse" address is required. Because each connection is uniquely determined by the combination of the local address and the remote address, it is not a big deal to bundle two sets of interfaces with one address as long as the remote address is different. In order to inform the Socket interface implementation do not let it be bundled with another socket because an address has been used by one set of interfaces, and the application can set the SO_REUSEADDR option before the bind () call. Note that this option is interpreted only when bind () is called, so it is not necessary (but harmless) to set the option for a socket that does not share the address, or to set or clear this option if bind () has no effect on this or other set of interfaces.  
    An application can open the So_keepalive option so that the socket implementation allows the "Keep-active" package to be used in the case of TCP connections. A set of interface implementations is not required to support "Keep-active", but if supported, the specific semantics will be related to implementation.

The Tcp_nodelay option prohibits the Nagle algorithm. The Nagle algorithm reduces the number of fragmented small packets sent by the host by storing unacknowledged data in buffers until a package is sent together. But for some applications, this algorithm will degrade system performance. So tcp_nodelay can be used to turn this algorithm off. The application writer sets the Tcp_nodelay option only if it knows exactly what it is and does, because it has a noticeable negative impact on network performance. Tcp_nodelay is the only option to use the IPPROTO_TCP layer, and all other options use the Sol_socket layer.
If the So_debug option is set, the socket provider is encouraged (but not required) to provide the appropriate debug information for the output. However, the mechanism of generating debugging information and the form of debugging information are beyond the scope of this specification.
SetSockOpt () supports the following options. Where "type" indicates the type of data referred to by optval.

In a TCP connection, a function such as recv defaults to blocking mode (block), that is, until the data arrives, the function does not return, and we sometimes need a timeout mechanism to return it after a certain amount of time, regardless of whether there is data coming, we will use the setsockopt () function:

int setsockopt (int s, int level, int optname, void* optval, socklen_t* Optlen);
Here we relate to a structure:
struct Timeval
{
time_t tv_sec;
time_t tv_usec;
};
Here the first field is in seconds, and the second field is in microseconds.
struct Timeval tv_out;
Tv_out.tv_sec = 1;
tv_out.tv_usec = 0;
Once this structure is populated, we can call this function in the following way:
SetSockOpt (FD, Sol_socket, So_rcvtimeo, &tv_out, sizeof (tv_out));(specific parameters can be man, or view MSDN)
This allows us to set the timeout mechanism for the recv () function, and recv () returns a value of 0 when the time of the tv_out set is exceeded and no data arrives.

The second is to introduce a multiplexing mechanism that listens to multiple socket connections at the same time.
int select (int n, fd_set* Readfds, fd_set* Writefds, fd_set* exceptfds, struct timeval* timeout);
Here comes the fd_set structure:
typedef struct FD_SET
{
U_int Fd_count;
int fd_array[fd_setsize];
}
Fd_count is the number of sockets contained in the FD_SET structure, fd_array the only array of int that contains the socket we want to listen to.
First we need to use Fd_set to add the sockets we want to listen to in the FD_SET structure:
Fd_set READFD;
Fd_set (FD, &AMP;READFD);
We then call the Select function:
Select (max_fd + 1, &AMP;READFD, NULL, NULL, NULL);(specific parameters can be man, or view MSDN)
Fd_isset (FD, &AMP;READFD);
Where MAX_FD is the largest of the socket we want to listen to, while calling select is to add it 1,readfd that we listen to the socket connection to be read, the third parameter is we listen to write operation socket connection, the fourth parameter for the exception, And the last parameter can be used to set the timeout, here also use the struct timeval structure, you can achieve the same effect as described earlier. Here, if the connection comes in, select returns a value greater than 0, and we call the Fd_isset macro to detect that the socket has data coming in (Fd_isset returns a value other than 0).

Finally, there is another way to implement non-blocking, which can play a role in some applications, especially when the Select () function listens to more than 1024 sockets (because the FD_SET structure has a 1024 limit on the number of sockets it can listen on in most UNIX systems. , if you want to break this limit and you have to modify the header file and recompile the kernel, we cannot use the Select multiplexing mechanism.
With the recv () function, we can call this:
Recv (FD, buf, sizeof (BUF), msg_dontwait);
Notice that we are using the MSG_DONTWAIT flag, which is to tell the recv () function to accept all data and return it immediately if there is data coming, without any data, without any waiting. With this mechanism, you can use the for () loop to listen for all connections when more than 1024 sockets are connected.

"Linux C" setsockopt detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.