免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 853 | 回复: 0
打印 上一主题 下一主题

select的参数问题:fd_set [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-11 22:56 |只看该作者 |倒序浏览

                that is, the total number  of bits that are set in readfds, writefds, exceptfds.
将相应的可操作的文件描述符对应的BIT置为1,select返回之后,如果要使用某个文件描述符,先要判断他的BIT是否为1。
可能有多个文件描述符同时处于可操作状态。
也可能超时,返回0;
例子:
用alarm来定时(30s)执行一个函数。主程序用了select。
select和alarm会冲突。alarm返回的时候select也会返回??????????
main()
{
signal(SIGALRM,sig_alarm);
sig_alarm(..);
for(;;)
{
......
select(....rdfds,NULL,NULL,NULL);
......
}
}
当alarm定时到时,select会返回的,其错误为EINTR,此时你应该检查select的返回值,如为EINTR则重新调用select
可以修改为在select中阻塞30秒,然后等到select返回的时候调用你的sig_alarm函数
。因为alarm和slect的实现都是通过setitimer发送SIGALRM信号来实现的.pselect中会阻塞SIGALRM信号,这样alarm函数发出的信号会被屏蔽掉  
2 fd_set的理解
1)dset是一个通过bit来标识文件描述符的数据结构,类似一个数组,select()的第一个参数实际上就是通知系统检查到哪个数组下标的时侯就停止继续检查,其目的是提高系统的处理速度。
2)创建了一个fd,再程序中,你的0,1,2若没有关掉的话,系统默认给你的fd是3。所以,你设定成2的话,讲接收不到对方的connect,但若设定成>3,例如,6,10,就可以了。n值要设定成最大的fd的值加1。
3
s = socket(AF_INET, SOCK_STREAM, 0);
//下面获取套接字的标志
if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
    //错误处理
}
//下面设置套接字为非阻塞
if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
    //错误处理
}
if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&  
    errno != EINPROGRESS) {
   //因为套接字设为NONBLOCK,通常情况下,连接在connect()返回
   //之前是不会建立的,因此它会返回EINPROGRESS错误,如果返回
   //任何其他错误,则要进行错误处理
}
if (0 == retcode) {  //如果connect()返回0则连接已建立
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }
    //下面是连接成功后要执行的代码
     
    exit(0)
}
FD_ZERO(&rdevents);
FD_SET(s, &rdevents);  //把先前的套接字加到读集合里面
wrevents = rdevents;   //写集合
exevents = rdevents;   //异常集合
tv.tv_sec = 5;  //设置时间为5秒
tv_tv_usec = 0;
retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);
if (retcode < 0) {  //select返回错误???
    //错误处理
}
else if (0 == retcode) {  //select 超时???
    //超时处理
}
esle {
    //套接字已经准备好
    if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {
        //connect()失败,进行错处理
    }
    if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
        //getsockopt()失败,进行错处理
    }
    if (err != 0) {
        //connect()失败,进行错处理
    }
    //到这里说明connect()正确返回
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }
    //下面是连接成功后要执行的代码
     
    exit(0)
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/35079/showart_276088.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP