select阻塞怎么解除?急~~~~

tww8596 2009-09-08 03:46:57
先把代码贴上
while(TRUE)
{
fd_set rdfds;
FD_ZERO(&rdfds);
FD_SET(sockSrv,&rdfds);
while(1)
{

int retval=select(0,&rdfds,NULL,NULL,NULL);
printf("retval=%d\n",retval);
if(retval == SOCKET_ERROR)
{
printf("select failed!\n");
WSACleanup();
}
else
{
if(FD_ISSET(sockSrv,&rdfds))
{
sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
FD_SET(sockConn,&rdfds);
printf("connected from '%s'\n",inet_ntoa(addrClient.sin_addr));

}

else
{

send(sockConn,sendBuf,2357,0);
printf("传输文件字节数为%d\n",2357);
closesocket(sockConn);
}
}
}
}
我把建立连接后生成的套接字sockConn添加到文件描述符集合rdfds中,通过循环再执行SELECT,结果一直阻塞,什么原因?是我没准备好要发送的数据到缓冲区吗?
...全文
3326 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
冉航--小虾米 2010-08-18
  • 打赏
  • 举报
回复
注释一下:

timeval tim;
tim.sec = 1; //秒
tim.usec = 0; //微秒,请注意不是毫秒。
int retval=select(0,&rdfds,NULL,NULL,&tim);
冉航--小虾米 2010-08-18
  • 打赏
  • 举报
回复
int retval=select(0,&rdfds,NULL,NULL,NULL); 这句有错误,最后一个参数是超时设置,书上的这个代码运行部过去,我昨天也遇到过这个问题。


解决方法:
//系统结构体,不用自己声明
typedef struct timeval
{
long tv_sec; long tv_usec;
} timeval;
具体代码:
timeval tim;
tim.sec = 1;
tim.usec = 0;
int retval=select(0,&rdfds,NULL,NULL,&tim);
tww8596 2009-09-08
  • 打赏
  • 举报
回复
如果说只有对方发送数据过来才会有数据可读的话,那是不是说只有在数据的接收方才能用select()呢?
tww8596 2009-09-08
  • 打赏
  • 举报
回复
对了还有个疑问?
dclchj 2009-09-08
  • 打赏
  • 举报
回复
客气,我最近在忙一个网络程序,所以多交流对自已也有好处。
tww8596 2009-09-08
  • 打赏
  • 举报
回复
哦呵呵,我终于明白了。原来这样不算有数据可读了,难怪一执行到select处就一直阻塞了呢。谢谢你哈,把分全给你了,耽误你那么长时间呵呵~~
dclchj 2009-09-08
  • 打赏
  • 举报
回复
不算,要对方给你selsct中的套接字发送数据。
dclchj 2009-09-08
  • 打赏
  • 举报
回复
int select(
int nfds, //一般设0
fd_set FAR * readfds, //这三项各有用处,目前你用这项就足够,其它为NULL,
fd_set FAR * writedfds, //三项中至少一项不为NULL
fd_set FAR * exceptfds,
const struct timeval FAR * timeout //超时返回
)

struct timeval
{
long tv_sec; //秒
long tv_usec; //毫秒
};
tww8596 2009-09-08
  • 打赏
  • 举报
回复
呵呵,还想问个低级问题哦,我如果先把要发送的文件读入到缓冲区中,那么执行到select()的时候,算不算有数据可读呢?
dclchj 2009-09-08
  • 打赏
  • 举报
回复
3不完整:是处于监听中的套接字收到CONNECT消息,也是你第一次SELECT能返回的原因。
dclchj 2009-09-08
  • 打赏
  • 举报
回复
因为此时select没有收个任务有用的消息可以使它返回,而你又设了超时时间为NULL(无限),所以就一直停在这了。
你第一次select能成功是因为收到了连接请求;
三个条件,满足任意一个就返回。(或者设置超时时间N秒后就论结果都返回)
1。有数据可读(肯定否)
2。连接已被关闭,重启或终止
3。假如已调用LISTEN(sockConn没有调用listen)
tww8596 2009-09-08
  • 打赏
  • 举报
回复
我现在的程序是服务器send给客户端,在上面的程序中,服务器接受客户端发送来的请求,并创建sockConn套接字添加到rdfds中,再循环到select()处,为什么此时不能继续往下执行else的操作了呢?怎样才能执行send操作?
dclchj 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 tww8596 的回复:]
不好意思dclchj,先以为你不回了就走开了。
我想问的就是,什么情况下被认为是有数据可读呢?
[/Quote]
如果服务器端已经ACCEPT,客户端send给服务器,服务器用select(设置第二个参数)。就可以知道有数据可读。然后调用REVC。
tww8596 2009-09-08
  • 打赏
  • 举报
回复
不好意思dclchj,先以为你不回了就走开了。
我想问的就是,什么情况下被认为是有数据可读呢?
jaxe 2009-09-08
  • 打赏
  • 举报
回复
select第四个参数是可以设置select阻塞到超时时间接触阻塞,返回的。
dclchj 2009-09-08
  • 打赏
  • 举报
回复
当你给sockConn赋值后,将sockConn加入文件描述符。
然后重新循环运行select,
些时会检查是否:
1。有数据可读(肯定否)
2。连接已被关闭,重启或终止
3。假如已调用LISTEN(sockConn没有调用listen)

由于这三项都不能满足,而select第四个参数设置NULL(阻塞模式),所以就阻塞在select。
dclchj 2009-09-08
  • 打赏
  • 举报
回复
第4个参数
timeout 指向select()函数等待的最大时间的结构指针,如果设为NULL,则为阻塞操作
当没有连接挂起时,select就永远阻塞了。
dclchj 2009-09-08
  • 打赏
  • 举报
回复
是我想的不全,上面讨论的sockConn问题你对的。
tww8596 2009-09-08
  • 打赏
  • 举报
回复
为什么呢?应该会重新回到循环执行select()啊?判断sockConn有没有准备好,准备好了,执行else。帮忙看看
dclchj 2009-09-08
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 tww8596 的回复:]
我想弱弱的问一句哈,sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); 这句不算是给sockConn赋值了吗?
[/Quote]
刚发完贴子看到14楼,这里赋值执行了的话,下面的else就不会执行了呀。
加载更多回复(16)

69,379

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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