select的正确用法

Time: 七月 27, 2014
Category: tcp/ip internals

在linux平台上主要头文件如下:
/usr/include/sys/select.h
/usr/include/bits/select.h

select 相关的几个API如下:

       int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
               struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

参考man-pages,其中nfds的解释是:

nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

这里的nfds不表示fd_set的大小(实际上表示不了),而是指 the highest-numbered file descriptor + 1, the highest-numbered file descriptor也就是fd_set里fd的最大值。而且这个最大值不能超过 FD_SETSIZE

An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior.

至于为什么不能超过FD_SETSIZE,主要是因为fd_set是一个大小固定的bitmap,而这个bitmap的大小是通过FD_SETSIZE计算出来的。对于大于或者等于FD_SETSIZE的fd,FD_SET非法修改了不属于自己的内存。

所以每次FD_SET的时候都应该检查fd是否合法。

Leave a Comment