HPlogo HP 9000 Networking: BSD Sockets Interface Programmer's Guide > Chapter 3 Advanced Topics for Stream Sockets

Synchronous I/O Multiplexing with Select

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Glossary

 » Index

The select system call can be used with sockets to provide a synchronous multiplexing mechanism. The system call has several parameters which govern its behavior. If you specify a zero pointer for the timeout parameter, select will block until one or more of the specified socket descriptors is ready. If timeout is a non-zero pointer, it specifies a maximum interval to wait for the selection to complete.

A select of a socket descriptor for reading is useful on:

  • A connected socket, because it determines when data have arrived and are ready to be read without blocking; use the FIONREAD parameter to the ioctl system call to determine exactly how much data are available.

  • A listening socket, because it determines when you can accept a connection without blocking.

  • Any socket to detect if an error has occurred on the socket.

A select of a socket descriptor for writing is useful on:

  • A connecting socket, because it determines when a connection is complete.

  • A connected socket, because it determines when more data can be sent without blocking. This implies that at least one byte can be sent; there is no way, however, to determine exactly how many bytes can be sent.

  • Any socket to detect if an error has occurred on the socket.

select for exceptional conditions will return true for BSD sockets if out-of-band data is available to be read. select will always return true for sockets which are no longer capable of being used (e.g. if a close or shutdown system call has been executed against them).

select is used in the same way as in other applications. Refer to the select(2) man page for information on how to use select.

The following example illustrates the select system call. Since it is possible for a process to have more than 32 open file descriptors, the bit masks used by select are interpreted as arrays of integers. The header file sys/types.h contains some useful macros to be used with the select() system call, some of which are reproduced below.

/*
* These macros are used with select(). select() uses bit masks of
* file descriptors in long integers. These macros manipulate such
* bit fields (the file system macros use chars). FD_SETSIZE may
* be defined by the user, but must be = u.u_highestfd + 1. Since
* the absolute limit on the number of per process open files is
* 2048, FD_SETSIZE must be large enough to accommodate this many
* file descriptors.
* Unless the user has this many files opened, FD_SETSIZE should
* be redefined to a smaller number.
*/
typedef long fd_mask 
#define NFDBITS (sizeof (fd_mask) * 8 /* 8 bits per byte
#define howmany (x,y) (((x)+((y)-1))/(y))
typedef struct fd_set {
fd_mask fds_bits [howmany (FD_SETSIZE, NFDBITS)]; */
} fd_set;
#define FD_SET(n,p) ((p)->fds_bits[(n)/NFDBITS]
#|= (1 << ((n) % NFDBITS)))
#define FD_CLR(n,p) ((p)->fds_bits[(n)/NFDBITS]
#&= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n,p) ((p) ->fds_bits[(n)/NFDBITS]
#& (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) memset((char *) (p), (char) 0, sizeof (*(p)))

do_select(s)
int s; /* socket to select on, initialized */
{
struct fd_set read_mask, write_mask; /* bit masks */
int nfds; /* number to select on */
int nfd; /* number found */

for (;;) { /* for example... */
FD_ZERO(&read_mask); /* select will overwrite on return */
FD_ZERO(&write_mask);
FD_SET(s, &read_mask); /* we care only about the socket */
FD_SET(s, &write_mask);
nfds = s+1; /* select descriptors 0 through s */
nfd = select(nfds, &read_mask, &write_mask, (int *) 0,
(struct timeval *) 0);/* will block */
if (nfd == -1) {
perror( "select: unexpected condition" );
exit(1);
}
if (FD_ISSET(s, &read_mask))
do_read(s); /* something to read on socket s */
/* fall through as maybe more to do */

if (FD_ISSET(s, &write_mask))
do_write(s); /* space to write on socket s */
}
}
© 1997 Hewlett-Packard Development Company, L.P.