[Switch] detailed explanation of the socket select function by gooer

Source: Internet
Author: User

 

Prototype

Int Select (
Int NFDs,
Fd_set * Readfds,
Fd_set * Writefds,
Fd_set * Exceptfds,
Const struct timeval * Timeout
);

NFDs: this parameter is ignored and only works for compatibility.
Readfds: (optional) pointer pointing to a set of interfaces waiting for readability check.
Writefds: (optional) pointer pointing to a set of interfaces waiting for writable checks.
Required TFDs: (optional) pointer pointing to a set of interfaces waiting for error checks.
Timeout: Select () can wait for a maximum of time, and is null for blocking operations.

Timeout is the timeval structure used to set the select () wait time. Its structure is defined as follows:
Struct timeval
{
Time_t TV _sec; // second seconds
Time_t TV _usec; // microsecond subtle
};

Note:
This function is used to determine the status of one or more interfaces. For each set of interfaces, the caller can query its readability, writability, and error status information. The fd_set structure is used to represent a set of interfaces waiting for inspection. When a call returns, this structure contains a subset of the Set interface groups that meet certain conditions, and select () returns the number of sets of interfaces that meet the conditions. A set of macros can be used for fd_set operations. These macros are compatible with the Berkeley UNIX software, but their internal expressions are completely different.
The readfds parameter identifies the set of interfaces waiting for readability checks. If the set of interfaces is in the listen () Listening state, if a connection request arrives, the set of interfaces will be identified as readable, so that an accept () call can be completed without blocking. For other interfaces, readability means queuing data is available for reading. Or for an interface of the sock_stream type, the Recv () or recvfrom () operations can be completed without blocking because the Virtual Interface of this interface has been disabled. If the virtual circuit is "elegantly" aborted, The Recv () will return immediately if it does not read data. If the virtual circuit is forcibly reset, The Recv () will return immediately if the wsaeconnreset error is returned. If the so_oobinline option is set, it checks whether out-of-band data exists (see setsockopt ()).
The writefds parameter identifies the set of interfaces waiting for the writefds check. If a set of interfaces is being connected (non-blocking), writability means that the connection is established smoothly. If the set of APIS is not in the connect () call, writability means that the send () and sendto () calls will be completed without blocking. [However, it does not indicate how long this guarantee will take effect, especially in a multi-threaded Environment 〕.
The required TFDs parameter identifies a set of interfaces waiting for the existence of out-of-band data or indicating an error condition check. Note that if the so_oobinline option is set to false, you can only use this method to check whether out-of-band data exists. For the so_stream interface, the connection suspension and keepalive errors caused by the remote end will be treated as errors. If the set of interfaces is connecting to connect () (non-blocking), the connection attempt failure will be manifested in the limit TFDs parameter.
If you are not interested in any group of classes in readfds, writefds, or TFDs, you can leave it null.
In the Winsock. h header file, four macros are defined to operate the description word set. The fd_setsize variable is used to determine the maximum number of descriptive words in a set (the default value of fd_setsize is 64. You can use # define fd_setsize to change this value before including Winsock. h ). For internal representation, fd_set is represented as a queue with a set of interfaces, and the subsequent element of the last valid element is inval_socket. MACRO:
Fd_clr (S, * Set): deletes the description word s from the set.
Fd_isset (S, * Set): If S is a member of the set, it is non-zero; otherwise, it is zero.
Fd_set (S, * Set): add the description word s to the set.
Fd_zero (* Set): Initialize the set to null.
The timeout parameter controls the time when select () is completed. If the timeout parameter is a null pointer, select () will be blocked until a descriptive word meets the conditions. Otherwise, timeout points to a timeval structure, which specifies how long the select () call will wait before returning. If timeval is {0, 0}, select () returns immediately, which can be used to query the status of the selected interface. If it is in this state, the Select () call can be considered non-blocking, and all assumptions applicable to non-blocking calls apply to it. For example, the blocking hook function should not be called, and the implementation of Windows interfaces should not be yield.

Return Value:
The Select () call returns the total number of descriptive words that are in the ready state and already included in the fd_set structure. If the call times out, 0 is returned. Otherwise, the socket_error is returned. The application can use wsagetlasterror () obtain the error code.

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.
Wsaeinval: the timeout value is invalid.
Wsaeintr: cancels a (blocking) call through a wsacancelblockingcall.
Wsaeinss SS: A blocked Windows interface call is running.
Wsaenotsock: A descriptive word set contains non-interface elements.

Example:
Sock = socket (af_inet, sock_stream, 0 );

Struct sockaddr_in ADDR; // tell sock where to licence
Memset (& ADDR, 0, sizeof (ADDR ));
ADDR. sin_family = af_inet;
ADDR. sin_port = htons (11111); // Port
ADDR. sin_addr.s_addr = htonl (inaddr_any); // start listening on all IP addresses of the Local Machine

BIND (sock, (sockaddr *) & ADDR, sizeof (ADDR); // bind ....

Listen (sock, 5); // a maximum of 5 queues

Socket socka; // This is used to accept a connection.
Fd_set RfD; // sets the descriptor to test whether a connection is available.
Struct timeval timeout;

Fd_zero (& RFD); // always clears a descriptor set first.

Timeout. TV _sec = 60; // This is used by the SELECT statement.
Timeout. TV _usec = 0;

U_long ul = 1;

Ioctlsocket (sock, fionbio, & UL); // non-blocking connection

// Select is used now
Fd_set (sock, & RFD ); // put sock into the descriptor set to be tested, that is, put sock into RfD so that the sock will be tested during the next call to select to test RfD (because we put sock into the RDF) a descriptor set can contain multiple tested descriptors,
If (select (sock + 1, & RfD, 0, & timeout) = 0)
{// This braces are connected. If the return value is 0, the time exceeds the specified Timeout time.

// Process ....

}

If (fd_isset (sock, & RFD ))
{// There is a descriptor ready

Socka = accept (sock,); // one is used to test reading and the other is used to test writing.

Fd_zero (& RFD );

Fd_zero (& WFD );

Fd_set (socka, & RFD); // put socka into the read descriptor set

Fd_set (sockb, & RFD); // put sockb into the read descriptor set

Fd_set (socka, & WFD); Put socka into the write descriptor set

Fd_set (sockb, & WFD); Put sockb into the write descriptor set

If (socket_error! = Select (0, & RfD, & WFD,) // test the two descriptor sets and never time out. RfD is only used to test read WFD and only used to test write.

{// No error

If (fd_isset (socka, & RFD) // a readable

{...}

If (fd_isset (sockb, & RFD) // B readable

{...}

If (fd_isset (socka, & WFD) // socka writable

{...}

If (fd_isset (sockb, & WFD) // sockb writable

{...}

}

Ii. Linux C

Select (I/O multi-work mechanism)


Header file

# I nclude <sys/time. h>
# I nclude <sys/types. h>
# I nclude <unistd. h>

Define functions

Int select (int n, fd_set * readfds, fd_set * writefds, fd_set * contains TFDs, struct timeval * timeout );

Function Description

Select () is used to wait for the state change of the description word of the file. Parameter n represents the largest file descriptive word plus 1. The readfds, writefds, and limit TFDs parameters are called descriptive phrases and are used to return the reading, writing, or exception of the descriptive word. The macro below provides a way to deal with these three descriptive phrases:
Fd_clr (inr fd, fd_set * Set); used to clear the related FD bits in the description phrase set.
Fd_isset (int fd, fd_set * Set); used to test whether the bits of the related FD in the phrase set are true.
Fd_set (int fd, fd_set * Set); used to set the FD bit in the description phrase set.
Fd_zero (fd_set * Set); used to clear all bits of the phrase set.

Parameters

Timeout is the timeval structure used to set the select () wait time. Its structure is defined as follows:
Struct timeval
{
Time_t TV _sec;
Time_t TV _usec;
};

Return Value

If the timeout parameter is set to null, select () does not have timeout.

Error Code

If execution is successful, the number of changes in the state of the description word in the file is returned. If 0 is returned, it indicates that the time before the State of the description word changes has exceeded the timeout time. If an error occurs,-1 is returned, the error cause is stored in errno. The value of readfds, writefds, limit TFDs, and timeout parameters becomes unpredictable.
The description of the ebadf file is invalid or the file is closed.
Eintr this call is interrupted by the signal
The value of N is negative.
Insufficient enomem core memory

Example

Common Program snippets: fs_set readset;
Fd_zero (& readset );
Fd_set (FD, & readset );
Select (FD + 1, & readset, null );
If (fd_isset (FD, readset ){......}

The following is a simple usage of select in Linux.

# I nclude <sys/time. h>
# I nclude <stdio. h>
# I nclude <sys/types. h>
# I nclude <sys/STAT. h>
# I nclude <fcntl. h>
# I nclude <assert. h>

Int main ()
{
Int keyboard;
Int ret, I;
Char C;
Fd_set readfd;
Struct timeval timeout;
Keyboard = open ("/dev/tty", o_rdonly | o_nonblock );
Assert (Keyboard> 0 );
While (1)
{
Timeout. TV _sec = 1;
Timeout. TV _usec = 0;
Fd_zero (& readfd );
Fd_set (keyboard, & readfd );
Ret = select (Keyboard + 1, & readfd, null, null, & timeout );
If (fd_isset (keyboard, & readfd ))
{
I = read (keyboard, & C, 1 );
If ('\ n' = C)
Continue;
Printf ("hehethe input is % C \ n", C );

If ('q' = C)
Break;
}
}
}

Address: http://blog.csdn.net/gooer/archive/2009/03/02/3951135.aspx

[Switch] detailed explanation of the socket select function by gooer

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.