Berkeley Sockets Select() Call

Started by
5 comments, last by rufeoo 17 years, 1 month ago
Can anyone demystify the need for the first parameter on the select call? Man pages define the function as: int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); Unix Network tutorials mention sending the (maximum descriptor + 1) as the value <n>. Windows Network tutorials say the value is ignored. What is the history of this parameter? Is it important for a unix compatible server application?
Advertisement
Yes, it is important for a UNIX socket implementation, because it tells the select() call how far into the fd_Set bitset to look for active file descriptors (on UNIX, fd_set is a bit vector).

On Windows, fd_set is an array, and file descriptors are handles, not small integers, so it's ignored.
enum Bool { True, False, FileNotFound };
On UNIX, is FD_ISSET() just a masking of a bit vector(fd_Set)?

Is the list of file descriptors stored by the operating system, and the maximum descriptor tells the OS where to stop its search for active fds?

(Thus an overestimated value could cause the operating system to look beyond the necessary descriptors?)

As you noted, hplus0603, the windows implementation of an fd_set is an array:
typedef struct fd_set {        u_int fd_count;               /* how many are SET? */        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */} fd_set;


This array is traversed by the windows macros (FD_ISSET, FD_SET, and FD_CLR) at the cost of O(N) time. Reasonable with the default FD_SETSIZE of 64.
That is correct, a value of max socket greater than the size of an fd_set will lead to illegal memory dereference.

You can define FD_SETSIZE on the command line to expand the size of the set, which on Windows defaults to 64, and on UNIX defaults to 1024 (because on UNIX, it's just a bit per descriptor, and it's O(1) instead of O(1)).

On Windows, for performance, you want to build the fd_set manually rather than using the macros (to avoid the N-squared), which means the Windows fd_set building code won't be portable.
enum Bool { True, False, FileNotFound };
Every UNIX process has a list of file descriptors. How are the bits in an fd_set mapped to the file descriptors of the process?
"man select" would be the easiest way to answer that question.

Here's a hint, though: Each UNIX file descriptor is a small integer (typically in the range 0 through 1023). The default number of bits in the fd_set is 1024. Coincidence? I think not.
enum Bool { True, False, FileNotFound };
Aye, I will be setting up a UNIX box Monday. Thanks for your insight hplus0603:)

This topic is closed to new replies.

Advertisement