We should set nonblocking mode on all network handles, and use select() or poll() to tell which network handle has data waiting. With this scheme, the kernel tells you whether a file descriptor is ready. It’s particularly important to remember that readiness notification from the kernel is only a hint; the file descriptor might not be ready anymore when you try to read from it. That’s why it’s important to use nonblocking mode when using readiness notification.
select的基本用法不再叙述。select uses descriptor sets, typically an array of integers, with each bit in each integer corresponding to a descriptor. For example, using 32-bit integers, the first element of the array corresponds to descriptors 0 through 31, the second element of the array corresponds to descriptors 32 through 63, and so on. All the implementation details are irrelevant to the application and are hidden in the fd_set datatype and the following four macros:void FD_ZERO(fd_set *fdset); /* clear all bits in fdset */
void FD_SET(int fd, fd_set *fdset); /* turn on the bit for fd in fdset */
void FD_CLR(int fd, fd_set *fdset); /* turn off the bit for fd in fdset */
int FD_ISSET(int fd, fd_set *fdset); /* is the bit for fd on in fdset ? */
We allocate a descriptor set of the fd_set datatype, we set and test the bits in the set using these macros, and we can also assign it to another descriptor set across an equals sign (=) in C. The constant FD_SETSIZE, defined by including
也就是说,使用select有一个限制,那就是它支持的文件描述符的数量,一般是1024。Many implementations have declarations similar to the following, which are taken from the 4.4BSD #ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
This makes us think that we can just #define FD_SETSIZE to some larger value before including this header to increase the size of the descriptor sets used by select. Unfortunately, this normally does not work. To see what is wrong, notice that Figure 16.53 of TCPv2 declares three descriptor sets within the kernel and also uses the kernel’s definition of FD_SETSIZE as the upper limit. The only way to increase the size of the descriptor sets is to increase the value of FD_SETSIZE and then recompile the kernel. Changing the value without recompiling the kernel is inadequate.
但是自己在实验的时候,发现输出1024,这是为什么呢?难道编译的是否内核里的宏定义直接覆盖用户提供的。#include <stdio.h>
#define FD_SETSIZE 512
#include <sys/types.h>
int main()
{
printf("%d\n", FD_SETSIZE);
}