select低级错误

本来不想吐槽的了,但是想到会有很多初学者犯了我所犯过的低级错误,找bug找了一天都找不到,还是决定写写这个比较隐性的错误把。(ps:本人菜鸟一枚)

如下典型的select多路复用套接口代码

fd_set         rset;  
int             socket_one, socket_two, maxfd;  
/*  一些列的初始化代码 */  
  
maxfd = socket_one > socket_two ? socket_one: socket_two;  
  
FD_ZERO(&rset);  
FD_SET(socket_one, &rset);  
FD_SET(socket_two, &rset);  
  
while(1){  
    select(maxfd + 1, &rset, NULL, NULL, NULL);  
    if(FD_ISSET(socket_one, &rset)){  
        /* 代码*/  
    }  
      
    if(FD_ISSET(socket_two, &rset)){  
        /*代码*/  
    }  
}  
一眼看上去似乎没有么多大的问题,但是把程序编译跑起来之后(假如你预计select第一次返回,socket_one可读,select第二次返回socket_two可读),情况并不如你所想。第二次当socket_two可读的时候,程序根本就不去读socket_two套接口!
出现这个隐性bug的原因在于select第一次返回的时候,只有socket_two在rset集合里面。因此当程序再次select的时候,相当于  

FD_ZERO(&rset);  
FD_SET(socket_one, &rset);  
select(maxfd + 1, &rset, NULL, NULL, NULL);
也就是说第二次的select只是检测socket_one是否可读,socket_two是否可读已经不能检测到!正确的代码应该如下:

fd_set          rset, allset;/*添加一个allset的变量,存储所有想要检查的套接口*/  
int             socket_one, socket_two, maxfd;  
/*  一些列的初始化代码 */  
  
maxfd = socket_one > socket_two ? socket_one: socket_two;  
  
FD_ZERO(&allset);  
FD_SET(socket_one, &allset);  
FD_SET(socket_two, &allset);  
  
while(1){  
        rset = allset;/*每次循环都应恢复,这一步是最关键的*/  
    select(maxfd + 1, &rset, NULL, NULL, NULL);  
    if(FD_ISSET(socket_one, &rset)){  
        /* 代码*/  
    }  
      
    if(FD_ISSET(socket_two, &rset)){  
        /*代码*/  
    }  
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值