Sign in to follow this  
rufeoo

Berkeley Sockets Select() Call

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
"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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this