TCP/IP,Linux多路IO模型select,select的作用,用法,限制,监听上限的修改方法,代码示例
O、单个服务器连接多个客户端
1、服务器主机一般无法避免要与大量客户机进行连接并通信,
2、不管使用多进程还是多线程,庞大的连接量都会迅速将服务器的进程或线程资源消耗光,
3、Linux系统内核提供了多路IO模型select,poll,epoll进行单进程多连接的维护,Windows也有类似的模型方便在单进程中维护多个连接。
4、这里的“模型”听起来和编程似乎脱节了,只要知道这就是函数就可以,例如select函数,poll函数,epoll函数,就和编码联系上了。
一、select模型
内核监听函数:select
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
1、这里select函数的第一个参数nfd是当前最大文件描述符+1,例如当前进程中有文件描述符3,4,5,6,7,传给select的nfd的值就是7+1=8
2、第2,3,4个参数分别表示所监听的文件描述符的“可读readfds()”,“可写writefds()”,“异常”事件的文件描述符容器,异常事件是内核给系统函数用的,进程中用的较少。
3、最后一个参数设定等待事件,可以为永久,可以为指定时长
4、这个函数的返回值返回的是所监听的所有文件描述符中满足条件的文件描述符的个数,满足的条件分别为读,写,异常,当有文件描述符3,4,5,6同时被监听时,3,4满足读,5,6满足写,3,4,5,6都满足异常,则返回8,以此类推。
5、出错返回-1
6、一开始的select监听的是唯一一个用于给accept监听的文件描述符,建立连接是一个写事件
二、文件描述符容器fd_set和函数:
1、fd_set是Linux提供的文件描述符容器,理解为是一个fd的set容器就可以,对这个容器的操作函数也有提供。
void FD_CLR(int fd, fd_set *set);//将fd从set中清除,就是将该位置为0
int FD_ISSET(int fd, fd_set *set);//判断fd是否在集合中
void FD_SET(int fd, fd_set *set);//将fd加入到set集合中
void FD_ZERO(fd_set *set);//将set清空,一般用于初始化一个文件描述符集合
2、超时时间结构体:
//相对时间秒,微秒
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};//相对时间秒,微秒
//绝对时间秒,纳秒
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};//绝对时间秒,纳秒
三、select作用
1、select是内核提供的监听函数,用来避免进程本身被阻塞于accept,read,write这个的函数中,而将这三种阻塞情况都封装为“事件”,由select统一监听,因此select可以保证在一个进程中可以同事监听多个文件描述符的状态,这样就实现了但服务器进程服务多个客户端的目的。
2、select在没有符合事件的文件描述符是也会处于阻塞状态,有满足事件的文件描述符时,例如,监听服务端的监听套接字有客户端连上了,就满足了写事件,select会返回,但返回的是有事件的描述符的总数,需要使用FD_ISSET定位监听描述符或者其他描述符的状态,并分别给出相应的处理函数。
3、当select监听到有符合条件的文件描述符时,会对应的修改传入的三个集合的内容,例如传入的readfdset中设置了文件描述符3,4,5,6,select监听到了4和5符合写事件,返回总数2,此时readfdset中的值也会变成只有4和5,可以通过readfdset和FD_ISSET函数遍历所有文件描述符定位出所有符合读事件的文件描述符。
四、select的限制:
1、进程中最大能打开的文件描述符数量为1024,select的监听上限也是这么多。
2、select只能返回符合条件的文件描述符的总数,遍历时只能通过for遍历[1-1023]所有文件描述符挨个找,不过可以通过程序员定义一个数组等容器维护文件描述符的信息,等返回总数后从描述符容器中寻找,避免查找所有文件描述符降低效率。