Chinaunix首页 | 论坛 | 博客
  • 博客访问: 426195
  • 博文数量: 47
  • 博客积分: 1669
  • 博客等级: 上尉
  • 技术积分: 585
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-04 23:27
文章分类

全部博文(47)

文章存档

2011年(23)

2010年(24)

分类: LINUX

2011-01-08 19:55:06

最近写一个通信程序,用了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) |
给主人留下些什么吧!~~

whyliyi2011-01-09 10:15:57

chxlinux: .....
????怎么了

chxlinux2011-01-09 00:49:05