对于服务器端,我们运用select函数,那么这个函数是干什么的呢?当我们应用层调用这个函数的时候,我们就相当于告诉内核,我在等待套接字数据,当数据到来的时候你给我返回。当返回的时候,我们的应用层收到这个返回信息,我们回去检查有哪些套接字处于数据可读或者可写的状态。然后再调用响应的函数去操作,比如用recv函数去读。select可以去等待多个套接字,就是可以等待多个客户端的连接。当我检测到多个套接字的时候,即多个客户端连接的时候,去处理每个客户端。
首先我们看一下select函数。
先说一个结构体,struct fd_set 这个结构体相当于一个集合,这个集合里面存放的是文件描述符,我们可以通过 一些宏由人为来操作,比如:
清空集合FD_ZERO(fd_set *)。
将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set*)。
将一个给定的文件描述符从集合中删除FD_CLR(int,fd_set*)。
检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。
FD_ISSET(0,&testfds)检测文件可否读写,如果可以读写,返回正值。
fd_set * readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的。即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
fd_set * writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的。
fd_set * writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的。
负值:select错误
正值:某些文件可读写或出错
0:等待超时,没有可读写或错误的文件