如何判断非阻塞模式的socket连接是否可读可写?

yzhgr 2005-06-05 04:46:53
大家都说select是用在阻塞模式下,如果采用非阻塞模式,我想知道某个socket连接是否可以读,是否可以写该怎么判断啊?希望大虾指教!!
...全文
791 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
AntonlioX 2005-06-28
  • 打赏
  • 举报
回复
收藏啊
jerry 2005-06-06
  • 打赏
  • 举报
回复
NULL 会阻塞的, 如果仅仅是检查是否可读写, 应将时间设为0
aiyue2010 2005-06-06
  • 打赏
  • 举报
回复
不要把超时设为0,用NULL试试ti = select(NULL,&fdRead,&fdWrite,NULL,NULL);
aiyue2010 2005-06-06
  • 打赏
  • 举报
回复
send返回的错误代码是什么?按照返回错误往下查找原因
yzhgr 2005-06-06
  • 打赏
  • 举报
回复
ti = select(NULL,&fdRead,&fdWrite,NULL,&mWaitTime);
if (FD_ISSET(ts,&fdRead))
CanRcvFlag[i] = true; //判断第i路是否可读
if (FD_ISSET(ts,&fdWrite))
CanSendFlag[i] = true; //判断第i路是否可写
else
CanSendFlag[i] = false;


上面的语句中select的返回值是2,
CanSendFlag[i] = true,但是这种情况下send返回的是-1,什么意思?为什么检测到线路是可以发送的, 但是send却发送失败呢?
aiyue2010 2005-06-06
  • 打赏
  • 举报
回复
若将超时值设置为( 0 , 0),表明s e l e c t会立即返回,允许应用程序对s e l e c t操作进行“轮询”。出于对性能方面的考虑,应避免这样的设置。。s e l e c t成功完成后,会在f d _ s e t结构中,返回刚好有未完成的I / O操作的所有套接字句柄的总量。若超过t i m e v a l设定的时间,便会返回0。不管由于什么原因,假如s e l e c t调用失败,都会返回S O C K E T _ E R R O R。
判断select返回值了吗?
aiyue2010 2005-06-06
  • 打赏
  • 举报
回复
错误代码是多少?
recv和send函数如果返回SOCKET_ERROR,判断是否为WSAEWOULDBLOCK错误?对于非锁定套接字recv函数返回WSAEWOULDBLOCK说明:没有收到数据,稍后再次检查。
recv和send函数如果返回0,说明数据接收结束了。
yzhgr 2005-06-06
  • 打赏
  • 举报
回复
期待中……
yzhgr 2005-06-06
  • 打赏
  • 举报
回复
1099218是我开的一个群号,有兴趣的朋友希望能够加入一起讨论!谢谢
yzhgr 2005-06-06
  • 打赏
  • 举报
回复
aiyue2010(亚伦)
你所说的“轮询”是不是指不停地用select检查网络的状况??

我是基本不停的在用select检查的,如果不是,你的“轮询”指的是什么?


yzhgr 2005-06-06
  • 打赏
  • 举报
回复
krh2001(边城浪子)
如果时间设成0,好象select模型也不能立刻检查到网络的最新情况,比如如果将网络的网线断开,select检查的结果仍然是可发送的,这时send是成功的,但一段时间后会检查到不可发送,如果再将网络恢复,select在一段时间的延迟后select检测可发送(但此时select的返回值是2),但send是-1怎么回事?为什么select检测到网络恢复可以发送了,但send却不能发送呢?


请解释解释!!!
aiyue2010 2005-06-06
  • 打赏
  • 举报
回复
时间设为0,s e l e c t会立即返回,应用程序需要对s e l e c t操作进行“轮询”,而楼主好像没有这样做。这就可能是导致问题的原因(我不敢肯定)
yzhgr 2005-06-05
  • 打赏
  • 举报
回复
int mComm::Run()
{
// TODO: Add your specialized code here and/or call the base class
while (Loop)
{
JudgeBlocking();
MainProc();
Sleep(1);
}
return CWinThread::Run();
}


void mComm::JudgeBlocking()
{
int i,ti;
char * telnum;
SOCKET ts;
timeval mWaitTime;
fd_set fdRead,fdWrite;

mWaitTime.tv_sec = 0;
mWaitTime.tv_usec = 0;
FD_ZERO(&fdRead);
FD_ZERO(&fdWrite);

for (i=0;i<MAXCLIENTNUM;i++)
{

ts = theCommApp->GetSocket(i); //得到第i路的socket号
if(ts!=NULL)
{
FD_SET(ts,&fdRead);
FD_SET(ts,&fdWrite);
ti = select(NULL,&fdRead,&fdWrite,NULL,&mWaitTime);
if (FD_ISSET(ts,&fdRead))
CanRcvFlag[i] = true; //判断第i路是否可读
if (FD_ISSET(ts,&fdWrite))
CanSendFlag[i] = true; //判断第i路是否可写
else
CanSendFlag[i] = false;
FD_ZERO(&fdRead);
FD_ZERO(&fdWrite);
}
}
}

int RcvPoint[MAXCLIENTNUM];
void mComm::MainProc()
{
int i,ti;
ti=0;

for (i=0;i<MAXCLIENTNUM;i++)
{
if (CanRcvFlag[i])
{
CanRcvFlag[i] = false;
ti = recv(theCommApp->GetSocket(i),&Rcvbuff[i][RcvPoint[i]],MAXPACKAGELEN-RcvPoint[i],0); //MAXPACKAGELEN定义为1000
if ((ti!=SOCKET_ERROR)&&(ti>0))
{
…… //读接收到的数据
}
else
{
…… //出错
}
}
}
}


为什么CanRcvFlag[i])已经判断为TRUE了,就是有数据可读了,为什么还会出现recv返回SOCKET_ERROR

同样用判断出CanSendFlag[i]为TRUE了,为什么send还返回SOCKET_ERROR?为什么select判断的结果和实际的不相符合?????
Tranquillo 2005-06-05
  • 打赏
  • 举报
回复
还可以用信号驱动吧,用WsaAsyncSelect
Kudeet 2005-06-05
  • 打赏
  • 举报
回复
仍然可以用select来判断某个socket是否可以读写吗?
==
可以,代码参考
http://search.csdn.net/Expert/topic/2057/2057746.xml?temp=.6641046
yzhgr 2005-06-05
  • 打赏
  • 举报
回复
楼上的什么意思?对于非阻塞模式,仍然可以用select来判断某个socket是否可以读写吗?如果可以的话能否例个事例?谢谢!
Kudeet 2005-06-05
  • 打赏
  • 举报
回复
select模型一般和多线程结合用,分别建立数据的读写两个线程,在线程里循环判断套接字上是否存在数据,或者能否向一个套接字写入数据
yzhgr 2005-06-05
  • 打赏
  • 举报
回复
另外还想问一下如果是非阻塞模式的,利用recv和send函数如果返回SOCKET_ERROR 或0 应该如何处理?

18,356

社区成员

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

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