winsocket编程关于select函数

lkwalk 2001-12-10 04:53:19
我在编写winsocket程序时,明明端口有数据,但调用select函数,返回值却总是0,屏蔽掉select函数部分,程序正常执行,为什么?请教各位大虾!!!
...全文
440 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
lkwalk 2001-12-13
  • 打赏
  • 举报
回复
问题基本解决,我是在一个动态连接库中封装了recv ,send 操作,这个动态连接库完成SSl认证等相关工作,程序中的connect函数也已经封装过了,这样引起在程序中select 时始终 返回不正确的问题,我再查查ssl的相关知识,然后再详细解决问题!


这个问题就到这儿了,谢谢大家参与,特别要感谢superdreamer(超级梦想家)的热心帮助!!!
superdreamer 2001-12-12
  • 打赏
  • 举报
回复
socket默认情况下是阻塞的,除非你用WSAAsyncSelect OR select 就变成NOBBLOCKING,
将阻塞设为非阻塞如下:
int opt=1;
ioctlsocket(sock,FIONBIO,&opt)
若opt=0就是阻塞的了
lkwalk 2001-12-12
  • 打赏
  • 举报
回复
先谢谢你们了!
请问怎么设置socket的阻塞与非阻塞状态?
superdreamer 2001-12-12
  • 打赏
  • 举报
回复
我不知你下面的是干什么的:
if( ( GThreadType==SERVER && CS->ServiceType==PROXY ) ¦¦
( GThreadType==CLIENT && CS->ServiceType==GATEWAY ) )
BufferLen = CS->SSLSock->SSL_recv(sock,Buffer,BUFFSIZE,0);
有可能你的条件满足时,没数据,所以就阻塞在哪儿,但有数据时,该条件不满足,但SOCK已阻塞,所以下面的RECV就收不到,你查查看,是不是呢?
lkwalk 2001-12-12
  • 打赏
  • 举报
回复
盼复!
lkwalk 2001-12-12
  • 打赏
  • 举报
回复
我在线程中使用的上述程序代码!请高手们快来指教!
lkwalk 2001-12-12
  • 打赏
  • 举报
回复
问题还没有解决!!!!
superdreamer 2001-12-11
  • 打赏
  • 举报
回复
楼上的搞反了吧,你用SELECT为什么不用FD_ISSET()呢?
ccf123 2001-12-11
  • 打赏
  • 举报
回复
如果你要发数据用select(sock+1,&s,NULL,NULL,NULL);
if(FD_ISSET(sock,&s) ,你可以发了。send it


如果你要收数据用select(sock+1,NULL,&s,NULL,NULL);
if(FD_ISSET(sock,&s) ,你可以收了。recv it



lkwalk 2001-12-11
  • 打赏
  • 举报
回复
请大家多关注
lkwalk 2001-12-11
  • 打赏
  • 举报
回复
TO:superdreamer(超级梦想家) 
忘记给你说明一个重要情况,其实select()可以正确返回,时间太长了可能得等上10分钟,这样发送方早已经超时了!!!谢谢
lkwalk 2001-12-11
  • 打赏
  • 举报
回复
select()函数第一个参数实际上是没用的,只是为了与早期版本兼容才留了下来,我照你说的是了还是有问题,返回值仍然是0,另外FD_ISSET()函数在这里是可以不用的因为只有一个socket被选择,再次谢谢!再帮助分析一下!!!
superdreamer 2001-12-11
  • 打赏
  • 举报
回复
你把SELECT()的最后一个参数设为空指针,另你没有用FD_ISSET(sock,&s)函数,你的SELECT()函数好象也有问题!
select(sock+1,&s,NULL,NULL,NULL);
if(FD_ISSET(sock,&s)
{
recv()
}
试试
lkwalk 2001-12-11
  • 打赏
  • 举报
回复
谢谢superdreamer(超级梦想家) !!!下面是相关代码
//这是类中的一个成员函数 数据接受函数
//外部定义
fd_set s;
struct timeval TimeOut;
TimeOut.tv_sec = 1;
TimeOut.tv_usec = 0;
int GSocket::GRecv( SOCKET sock )
{

//Test whether the socket is ready.
//Set time out 100 second.

int GRet = 0;
int times = 0;
int retval=0;
s.fd_array[0] = sock;

s.fd_count = 1;
//屏蔽掉while循环程序即可接受到数据
while( GRet == 0 )
{ FD_ZERO(&s);
FD_SET(sock,&s);
if(!(CS->client)||!(CS->server)) return GATE_CLOSE;
//s.fd_count = 1;
GRet = select(NULL,&s,NULL,NULL,&TimeOut);
}

if( GRet == SOCKET_ERROR ) return GATE_SOCKERR;
//Sleep(5);

//Get length of the data that can be recieved from client.
/* if( ioctlsocket(sock,FIONREAD,(unsigned long *)&BufferLen) == SOCKET_ERROR )
{
return GATE_SOCKERR;
}
*/
// if(!BufferLen) return GATE_BUFEMPTY;

//Allocate memory as buffer to store client data.
//BufferLen=0;
/*if(BufferLen>800)
Buffer = new char[BufferLen*15];
else
*/
Buffer = new char[BUFFSIZE];
memset(Buffer,0,BUFFSIZE);//sizeof(Buffer));
//Recieve request data from client.

if( ( GThreadType==SERVER && CS->ServiceType==PROXY ) ||
( GThreadType==CLIENT && CS->ServiceType==GATEWAY ) )
BufferLen = CS->SSLSock->SSL_recv(sock,Buffer,BUFFSIZE,0);
else

BufferLen = recv( sock,Buffer,BUFFSIZE,0 );
if (BufferLen==SOCKET_ERROR)return SOCKET_ERROR;
if(!BufferLen) return GATE_BUFEMPTY;
return GATE_SUCCESS;
}
lkwalk 2001-12-11
  • 打赏
  • 举报
回复
谢谢大家,不过谁能猜想一下为什么我的select()要等10多分钟才能返回可读,明显早有数据了,参照上面我的几个 帖子
notions 2001-12-11
  • 打赏
  • 举报
回复
你在select之前应调用
u_long data ;
rval = ioctlsocket( sock , FIONBIO , (u_long*)&data) ;
superdreamer 2001-12-10
  • 打赏
  • 举报
回复
肯定是你的SELECT调用有问题,代码贴出来大家看看

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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