select返回1后,fd_isset返回0

dodo_check 2010-01-06 01:59:35
使用默认创建的阻塞SOCKET,在线程中执行select对socket进行可读的监控,select返回1,但是FD_ISSET为FALSE,无法执行recv,请教一下 为什么?



//线程函数中..
fd_set RSet;
FD_ZERO(&RSet);
FD_SET (hSocket,&RSet);

struct timeval tv;
tv.tv_sec = 30;
tv.tv_usec = 0;

int nRet = select(hSocket,&RSet,NULL,NULL,&tv); //nRet 返回1
if (nRet > 0)
{
if (FD_ISSET(hSocket,&RSet)) //判断为假,recv无法执行
{
nRet = recv(hSocket,...)
}

]

...全文
1206 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
testing2007 2010-12-03
  • 打赏
  • 举报
回复
真得很奇怪,我在自己的机器上执行了一下,没有出现你说的这种情况,机器配置:windows server 2003+vc6.0
wwwhhb4004 2010-01-11
  • 打赏
  • 举报
回复

mark
rightorwrong 2010-01-08
  • 打赏
  • 举报
回复
是因为你在FD_ISSET(hSocket,&RSet)时,RSet中已为0.你调试的时候可以看下
dodo_check 2010-01-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 rightorwrong 的回复:]
是因为你在FD_ISSET(hSocket,&RSet)时,RSet中已为0.你调试的时候可以看下
[/Quote]

不好意思,在Windows 没有找打类似 fd_isempty,请教 怎么样判断?
如果为空的话,可能是什么原因造成的?
dodo_check 2010-01-07
  • 打赏
  • 举报
回复
nRet 返回值为1
如果


//线程函数中..
fd_set errorfds;
FD_ZERO(&errorfds);
FD_SET (hSocket,&errorfds);

fd_set RSet;
FD_ZERO(&RSet);
FD_SET (hSocket,&RSet);

struct timeval tv;
tv.tv_sec = 30;
tv.tv_usec = 0;

int nRet = select(hSocket,&RSet,NULL,&errorfds,&tv); //nRet 返回1
if (nRet > 0)
{
if (FD_ISSET(hSocket,&errorfds)) //判断为假,弹对话框无法执行
{
AfxMessageBox("error");
}
if (FD_ISSET(hSocket,&RSet)) //判断为假,recv无法执行
{
nRet = recv(hSocket,...)
}

]



不知道那样判断错误对不对?

返回值仍然为1.但是检测不到有事件,FD_ISSET老是0
cppgp 2010-01-07
  • 打赏
  • 举报
回复
另外,对于reayi的回复,个人看法如下:
如果不需要检测是否可写,则 writefd 是需要设置为 NULL 的,至于 exceptfd 用来检测带外数据,正常的通信是用不到的,网络通信中只有有必要传输紧急数据时才用,因此绝大部分的 exceptfd 需要设置为 NULL。
linux和windows下select调用差别主要在两分面:
1. windows下第一个参数无所谓设置成多少,linux必须为管理的最大套接字加1。
2. windows下最后一个参数以常量的形式传递进去,不会被更改,linux下会更改该值为剩余的时间。
在做高并发管理时候,后者很容易导致讯里面的高cpu耗用,处理方法是在每个select前面重置timeout或者相关策略。
dodo_check 2010-01-07
  • 打赏
  • 举报
回复
不是的,是Windows平台..
cppgp 2010-01-07
  • 打赏
  • 举报
回复
select调用参数错误,你是linux平台吧?必须设置第一个参数为hSocket+1,可以看看man页,有详细说明的。如下:

int nRet = select(hSocket+1,&RSet,NULL,NULL,&tv); //nRet 返回1
dodo_check 2010-01-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 reayi 的回复:]
select的第一个参数其实是不用的,填0即可,
建议把writefds,exceptfds也传上去,返回1可能是发生异常也说不定,
每个都判断一下就知道是可读,可写,还是发生异常了
[/Quote]
不太明白 exceptfds怎么样用法?
FD_SET (??,&exceptfds);
??放什么异常对象?
reayi 2010-01-06
  • 打赏
  • 举报
回复
select的第一个参数其实是不用的,填0即可,
建议把writefds,exceptfds也传上去,返回1可能是发生异常也说不定,
每个都判断一下就知道是可读,可写,还是发生异常了

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧