使用默认创建的阻塞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,...)
}]
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,...)
}]
建议把writefds,exceptfds也传上去,返回1可能是发生异常也说不定,
每个都判断一下就知道是可读,可写,还是发生异常了
FD_SET (??,&exceptfds);
??放什么异常对象?
如果不需要检测是否可写,则 writefd 是需要设置为 NULL 的,至于 exceptfd 用来检测带外数据,正常的通信是用不到的,网络通信中只有有必要传输紧急数据时才用,因此绝大部分的 exceptfd 需要设置为 NULL。
linux和windows下select调用差别主要在两分面:
1. windows下第一个参数无所谓设置成多少,linux必须为管理的最大套接字加1。
2. windows下最后一个参数以常量的形式传递进去,不会被更改,linux下会更改该值为剩余的时间。
在做高并发管理时候,后者很容易导致讯里面的高cpu耗用,处理方法是在每个select前面重置timeout或者相关策略。
如果
//线程函数中..
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
不好意思,在Windows 没有找打类似 fd_isempty,请教 怎么样判断?
如果为空的话,可能是什么原因造成的?