Linux select()详解

 

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

ndfs:select监视的文件句柄数,视进程中打开的文件数而定,一般设为呢要监视各文件 中的最大文件号加一。  
readfds:select监视的可读文件句柄集合。  
writefds: select监视的可写文件句柄集合。  
exceptfds:select监视的异常文件句柄集合。  
timeout:本次select()的超时结束时间。

 

当readfds或writefds中映象的文件可读或可写或超时,本次select() 就结束返回。程序员利用一组系统提供的宏在select()结束时便可判 断哪一文件可读或可写。对Socket编程特别有用的就是readfds。 几只相关的宏解释如下:  

FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。  
FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。  
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。  
FD_ISSET(int fd, fdset *fdset):检查fdset联系的文件句柄fd是否  
可读写,>0表示可读写

 

 

补充关于select在异步(非阻塞)connect中的应用,刚开始搞socket编程的时候 
我一直都用阻塞式的connect,非阻塞connect的问题是由于当时搞proxy scan 
而提出的呵呵 
通过在网上与网友们的交流及查找相关FAQ,总算知道了怎么解决这一问题.同样 
用select可以很好地解决这一问题.大致过程是这样的: 

1.将打开的socket设为非阻塞的,可以用fcntl(socket, F_SETFL, O_NDELAY)完 
成(有的系统用FNEDLAY也可). 

2.发connect调用,这时返回-1,但是errno被设为EINPROGRESS,意即connect仍旧 
在进行还没有完成. 

3.将打开的socket设进被监视的可写(注意不是可读)文件集合用select进行监视, 
如果可写,用 
getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, sizeof(int)); 
来得到error的值,如果为零,则connect成功. 

在许多unix版本的proxyscan程序你都可以看到类似的过程,另外在solaris精华 

区->编程技巧中有一个通用的带超时参数的connect模块..

posted @ 2010-07-23 17:38  p2liu  阅读(359)  评论(0编辑  收藏  举报