The Select Model

来源:互联网 发布:2017淘宝生意差 编辑:程序博客网 时间:2024/05/17 21:38

 

1      The Select Model

1.1      APIs

The select function blocks for I/O operations until the conditions specified as parameters are met.

int select(

    int nfds,

    fd_set FAR * readfds,

    fd_set FAR * writefds,

    fd_set FAR * exceptfds,

    const struct timeval FAR * timeout

);

Note:

Any two of the parameters, readfds,writefds, or exceptfds, can be given as NULL. At least one must be non-NULL, and any non-NULL descriptor set must contain at least one handle to a socket.

 

FD_ZERO(*set) Initializes set to the empty set. A set should always be cleared before using.

FD_CLR(s, *set) Removes socket s from set.

FD_ISSET(s, *set) Checks to see if s is a member of set and returns TRUE if so.

FD_SET(s, *set) Adds socket s to set.

1.2      Five steps to use

1)  Initialize each fd_set of interest by using the FD_ZERO macro.

2)  Assign socket handles to each of the fd_set sets of interest by using the FD_SET macro.

3)  Call the select function and wait until I/O activity sets one or more of the socket handles in each fd_set set provided. When select completes, it returns the total number of socket handles that are set in all of the fd_set sets and updates each set accordingly.

4)  Using the return value of select, your application can determine which application sockets have I/O pending by checking each fd_set set using the FD_ISSET macro.

5)  After determining which sockets have I/O pending in each of the sets, process the I/O and go to step 1 to continue the select process.

1.3      Sameples

SOCKET  s;

fd_set  fdread;

int     ret;

// Create a socket, and accept a connection

// Manage I/O on the socket

while(TRUE)

{

    // Always clear the read set before calling

    // select()

    FD_ZERO(&fdread);

 

    // Add socket s to the read set

FD_SET(s, &fdread);

 

    if ((ret = select(0, &fdread, NULL, NULL, NULL))

        == SOCKET_ERROR)

    {

        // Error condition

    }

    if (ret > 0)

    {

        // For this simple case, select() should return

        // the value 1. An application dealing with

        // more than one socket could get a value

        // greater than 1. At this point, your

        // application should check to see whether the

        // socket is part of a set.

 

        if (FD_ISSET(s, &fdread))

        {

            // A read event has occurred on socket s

        }

    }

}