最近写一个通信程序,用了select这个函数,没想到这么一个简单的程序,我都没写好,还调了好久!其中很多
比较弱智的错误,贴出来,算是个笔记!
int select(int nfds,struct fd_set *readfds,struct fd_set* writefds,struct fd_set* exceptfds,
struct timeval *timeout)
ndfs:select监视的文件句柄数,视进程中打开的文件数而定,一般设为呢要监视各文件 中的最大文件号加一。
readfds:select监视的可读文件句柄集合。
writefds: select监视的可写文件句柄集合。
exceptfds:select监视的异常文件句柄集合。
timeout:本次select()的超时结束时间。(见/usr/sys/select.h, 可精确至百万分之一秒!)
当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表示可读写。
(关于fd_set及相关宏的定义见/usr/include/sys/types.h)
以上这些都是从这()复制来的,都一样,就不自己写了。重点是
我使用时出现的弱智错误。
timeout.sec = 2;
timeou.usec = 0;
FD_SET(fd, &readdfs);
while(1)
{
........
ret=select(max_fd,&readfds,NULL,NULL,&timeout) ;
if(ret == 0) continue;
else if(ret == -1)
printf("something unexpected hanpened...");
else
{.......}
........
}
错误(1):timeout值的设置放在了循环外,在第一超时返回后,timeout=0,因此select函数不断返回0。
解决方法:将timeout赋值在循环里实现,每次循环都需要给timeout赋值。
错误(2):FD_SET(fd, &readdfs);放在了循环外。当超时返回后,readfds被清为0,因此,以后根本无法去判断fd是否有消息。
解决方法:将FD_SET(fd, &readdfs)放在循环体内,每次超时都需要重新设置。
上边是两个比较弱智的错误,虽然不多,但是,用这种简单的函数,也能用倒我,这充分说明一个问题,不管是
大事小事,都需认真,人,贵在兢兢业业!
另外一个疑问:如果我这里select函数不设置超时,而是设置select中的readfds中所监测的 套接子超时,这样
在select函数会不会在套接子超时的时候返回0或者-1呢?
关于这一点,我写了程序验证了一下,发现不会!这是为何?套接子超时,这也是套接子的一个信号阿?为啥
select没有反应呢?
问题解决留个笔记,留下疑问有待解决!
阅读(4407) | 评论(2) | 转发(0) |