Windows method:
U_long mode = 0;
Ioctlsocket (S, fionbio, & mode );
Control as blocking mode.
U_long mode = 1;
Ioctlsocket (S, fionbio, & mode );
Non-blocking mode.
Setsockopt () Description:
Set Interface Options.
# Include <Winsock. h>
Int Pascal far setsockopt (socket S, int level, int optname,
Const char far * optval, int optlen );
S: Specifies the description of a set of interfaces.
Level: The level defined by the option. Currently, only sol_socket and ipproto_tcp layers are supported.
Optname: the option to be set.
Optval: pointer, pointing to the buffer that stores option values.
Optlen: the length of the optval buffer.
Note:
The setsockopt () function is used to set the option values of interfaces of any type and any status. Although there are options on different protocol layers, this function only defines the options at the highest "set interface" level. This option affects operations on the set interface, such as whether the expedited data is received in a common data stream, and whether the broadcast data can be sent from the set interface.
There are two sets of Interface Options: one is a Boolean option that allows or disables a feature, and the other is an integer or structure option. If a Boolean option is allowed, optval is directed to a non-zero integer. optval is not allowed to point to an integer equal to zero. For Boolean options, optlen should be equal to sizeof (INT); for other options, optval points to the integer number or structure containing the required options, and optlen is the length of the integer number or structure. The so_linger option is used to control actions in the following situations: the interface has queued data to be sent, and the closesocket () call has been executed. See the impact of the so_linger option on closesocket () semantics in the closesocket () function. The application creates a linger structure to set the corresponding operation features:
Struct linger {
Int l_onoff;
Int l_linger;
};
To allow so_linger, the application should set l_onoff to a non-zero value, set l_linger to zero or the required timeout value (in seconds), and then call setsockopt (). To allow so_dontlinger (that is, disabling so_linger), l_onoff should be set to zero and setsockopt () should be called ().
By default, a set of interfaces cannot be bound with a local address in use (see BIND ()). But sometimes it is necessary to "reuse" the address. Because each connection is uniquely determined by the combination of the local address and the remote address, as long as the remote address is different, binding two sets of interfaces with one address is not a major problem. To notify the implementation of Windows interface sets, do not bind an address to another interface because it has been used by one interface set. The application can set the so_reuseaddr option before BIND () is called. Note that this option is interpreted only when BIND () is called. Therefore, you do not need (but are harmless) to set this option for a set of APIs that do not share addresses, or in BIND () set or clear this option without affecting this or other sets of interfaces.
An application can enable the so_keepalive option to enable the "keep active" package for Windows interfaces over TCP connections. The implementation of a Windows interface does not need to support "persistence activity", but if it is supported, the specific semantics will be related to the implementation, rfc1122 "Internet host requirements-communication layer" section 4.2.3.6 shall be observed. If the connection fails due to "active", any call to this interface in progress will be returned with the wsaenetreset error. Any subsequent call will be returned with the wsaenotconn error.
The tcp_nodelay option disables the Nagle algorithm. The Nagle algorithm saves unconfirmed data into the buffer until a packet is sent together to reduce the number of small packets sent by the host. However, for some applications, this algorithm will reduce system performance. Therefore, tcp_nodelay can be used to disable this algorithm. The tcp_nodelay option is set only when the application writer has a definite understanding of its effect and is required, because it has a significant negative impact on network performance. Tcp_nodelay is the only option to use the ipproto_tcp layer. All other options use the sol_socket layer.
If the so_debug option is set, the Windows interface provider is encouraged (but not required) to provide the corresponding debugging information. However, the mechanism for generating debugging information and the form of debugging information are beyond the scope of this specification.
Setsockopt () supports the following options. "Type" indicates the data type specified by optval.
Option type meaning
So_broadcast bool allows an interface to transmit broadcast information.
So_debug bool records debugging information.
So_dontliner bool should not block or close the operation because the data is not sent. Setting this option is equivalent to setting the l_onoff element of so_linger to zero.
So_dontroute bool disallows path selection; direct transfer.
So_keepalive bool sends the "keep active" package.
So_linger struct linger far * stays if no data is sent when it is disabled.
So_oobinline bool receives out-of-band data in a conventional data stream.
So_rcvbuf int determines the buffer size for receiving.
So_reuseaddr bool allows you to bind an interface with an existing address (see BIND ()).
So_sndbuf int specifies the size of the sending buffer.
Tcp_nodelay bool prohibits the combined Nagle algorithm from being sent.
Setsockopt () does not support the following BSD options:
Option name type meaning
The so_acceptconn bool interface is monitored.
So_error INT: Get the error status and clear it.
So_rcvlowat int receives low-level watermarks.
So_rcvtimeo int timeout.
So_sndlowat int sends a low-level watermark.
So_sndtimeo int timeout.
So_type int set interface type.
Set ip_options in the IP header.
Return Value:
If no error occurs, setsockopt () returns 0. Otherwise, the socket_error is returned. The application can obtain the error code through wsagetlasterror.
Error code:
Wsanotinitialised: before using this API, you must successfully call wsastartup ().
Wsaenetdown: A Windows interface is used to detect the failure of the network subsystem.
Wsaefault: optval is not a valid part of the process address space.
Wsaeinss SS: A blocked Windows interface call is running.
Wsaeinval: The level value is invalid, or the information in optval is invalid.
Wsaenetreset: the connection times out when so_keepalive is set.
Wsaenoprotoopt: unknown or not supported. Sock_stream APIs do not support the so_broadcast option. sock_dgram APIs do not support the so_dontlinger, so_keepalive, so_linger, and so_oobinline options.
Wsaenotconn: When so_keepalive is set, the connection is reset.
Wsaenotsock: The description is not a set of interfaces.
Usage
1. After closesocket () is called, the socket can be reused. Calling closesocket () usually does not immediately close the socket, but goes through the time_wait process.
Bool breuseaddr = true;
Setsockopt (S, sol_socket, so_reuseaddr, (const char *) & breuseaddr, sizeof (bool ));
2. If you want to force close soket that is already in the connection state after closesocket () is called, it does not go through the time_wait process:
Bool bdontlinger = false;
Setsockopt (S, sol_socket, so_dontlinger, (const char *) & bdontlinger, sizeof (bool ));
3. In the send () and Recv () processes, sometimes due to network conditions and other reasons, sending and receiving cannot be performed as expected. You can set the sending and receiving time limit:
Int nnettimeout = 1000; // 1 second
// Sending 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. when sending (), the returned bytes are actually sent out bytes (synchronized) or the bytes (asynchronous) sent to the socket buffer. The system sends and receives 8688 bytes (about
8.5 K); in the actual process, if the amount of data sent or received is large, you can set the socket buffer to avoid the continuous cyclic sending and receiving of send () and Recv:
// Receiving buffer
Int nrecvbuf = 32*1024; // set it to 32 K
Setsockopt (S, sol_socket, so_rcvbuf, (const char *) & nrecvbuf, sizeof (INT ));
// Sending Buffer
Int nsendbuf = 32*1024; // set it to 32 K
Setsockopt (S, sol_socket, so_sndbuf, (const char *) & nsendbuf, sizeof (INT ));
5. When sending data, do not copy data from the system buffer to the socket buffer to improve program performance:
Int nzero = 0;
Setsockopt (socket, sol_s0cket, so_sndbuf, (char *) & nzero, sizeof (nzero ));
6. When receiving data, do not copy the content of the socket buffer to the system buffer zone:
Int nzero = 0;
Setsockopt (S, sol_s0cket, so_rcvbuf, (char *) & nzero, sizeof (INT ));
7. Generally, when sending a UDP datagram, you want the data sent by the socket to have the broadcast feature:
Bool bbroadcast = true;
Setsockopt (S, sol_socket, so_broadcast, (const char *) & bbroadcast, sizeof (bool ));
8. when the client connects to the server, if the socket in non-blocking mode is in the connect () process, you can set the connect () delay until accpet () is called (this setting only
It plays a significant role in the non-blocking process and does not play a major role in blocking function calls)
Bool bconditionalaccept = true;
Setsockopt (S, sol_socket, so_conditional_accept, (const char *) & bconditionalaccept, sizeof (bool ));
9. if the send () process is not complete, and the data is not sent, but closesocket () is called, shutdown (S, sd_both) is used in the past.
Data will be lost.
Some specific programs require that the socket be closed after the data is sent out. You can set the program to meet the requirements:
Struct linger {
U_short l_onoff;
U_short l_linger;
};
Linger m_slinger;
M_slinger.l_onoff = 1; // when closesocket () is called, data is still not sent out. You can wait.
// If m_slinger.l_onoff = 0, disable it after closesocket () is called.
M_slinger.l_linger = 5; // set the wait time to 5 seconds.
Setsockopt (S, sol_socket, so_linger, (const char *) & m_slinger, sizeof (linger ));
See:
Processing in Linux:
Ioctl function name: IOCTL
Function: Controls I/O devices.
Usage: int IOCTL (INT handle, int cmd, [int * argdx, int argcx]);
Note of the macro defined in include/ASM/IOCTL. h:
# DEFINE _ ioc_nrbits 8 // The Bit Width of the number field, 8 bits
# DEFINE _ ioc_typebits 8 // The font width of the type field, 8 bits
# DEFINE _ ioc_sizebits 14 // The font width of the size field, 14 bits
# DEFINE _ ioc_dirbits 2 // The ction field's Bit Width, 2 bits
# DEFINE _ ioc_nrmask (1 <_ ioc_nrbits)-1) // mask of the ordinal field, 0x000000ff
# DEFINE _ ioc_typemask (1 <_ ioc_typebits)-1) // mask of the magic number field, 0x000000ff
# DEFINE _ ioc_sizemask (1 <_ ioc_sizebits)-1) // mask of the size field, 0x00003fff
# DEFINE _ ioc_dirmask (1 <_ ioc_dirbits)-1) // mask of the direction field, 0x00000003
# DEFINE _ ioc_nrshift 0 // shift of the ordinal number field in the entire field, 0
# DEFINE _ ioc_typeshift (_ ioc_nrshift + _ ioc_nrbits) // displacement of the magic number field, 8
# DEFINE _ ioc_sizeshift (_ ioc_typeshift + _ ioc_typebits) // displacement of the size field, 16
# DEFINE _ ioc_dirshift (_ ioc_sizeshift + _ ioc_sizebits) // direction field displacement, 30
/*
* Direction bits.
*/
# DEFINE _ ioc_none 0u // No Data Transmission
# DEFINE _ ioc_write 1u // write data to the device. The driver must read data from the user space.
# DEFINE _ ioc_read 2u // read data from the device. The driver must write data to the user space.
# DEFINE _ IOC (Dir, type, NR, size )/
(DIR) <_ ioc_dirshift) |/
(Type) <_ ioc_typeshift) |/
(NR) <_ ioc_nrshift) |/
(Size) <_ ioc_sizeshift ))
/*
* Used to create numbers
*/
// Construct a command number without Parameters
# DEFINE _ IO (type, NR) _ IOC (_ ioc_none, (type), (NR), 0)
// Construct the command number for reading data from the driver
# DEFINE _ ior (type, NR, size) _ IOC (_ ioc_read, (type), (NR), sizeof (size ))
// Write data commands to the driver
# DEFINE _ Iow (type, NR, size) _ IOC (_ ioc_write, (type), (NR), sizeof (size ))
// Used for bidirectional transmission
# DEFINE _ IOWR (type, NR, size) _ IOC (_ ioc_read | _ ioc_write, (type), (NR), sizeof (size ))
/*
* Used to decode IOCTL numbers ..
*/
// Parse the data direction from the command parameters, that is, write or read
# DEFINE _ ioc_dir (NR)> _ ioc_dirshift) & _ ioc_dirmask)
// Parse the phantom type from the Command Parameter
# DEFINE _ ioc_type (NR)> _ ioc_typeshift) & _ ioc_typemask)
// Parse the ordinal number from the Command Parameter
# DEFINE _ ioc_nr (NR)> _ ioc_nrshift) & _ ioc_nrmask)
// Parse the user data size from the Command Parameters
# DEFINE _ ioc_size (NR)> _ ioc_sizeshift) & _ ioc_sizemask)
/*... And for the drivers/sound files ...*/
# Define ioc_in (_ ioc_write <_ ioc_dirshift)
# Define ioc_out (_ ioc_read <_ ioc_dirshift)
# Define ioc_inout (_ ioc_write | _ ioc_read) <_ ioc_dirshift)
# Define iocsize_mask (_ ioc_sizemask <_ ioc_sizeshift)
# Define iocsize_shift (_ ioc_sizeshift)
Program example:
# Include <stdlib. h>
# Include <stdio. h>
# Include <sys/IOCTL. h>
Int main (void ){
..Int Stat;
/* Use func 8 to determine if the default drive is removable */
.. Stat = IOCTL (0, 8, 0, 0 );
. If (! Stat)
... Printf ("Drive % C is removable./N", getdisk () + 'A ');
.. Else
... Printf ("Drive % C is not removable./N", getdisk () + 'A ');
.. Return 0;
}