用CAsyncSocket类做的一个socket通讯程序,现想实现连接时的超时设置
查了一些代码,有人说到:
CAsyncSocket里面用SetSockOpt(SO_RCVTIMEO,&nRcvTimeOut,sizeof(nRcvTimeOut));可以设置接受超时。
但是查MSDN发现SO_RCVTIMEO是Berkeley Software Distribution (BSD) options not supported for SetSockOpt。
而且在代码中如上实现了一下,没有反应。
代码如下:
connect_to_server()
{
   CltSkt.Create(0,SOCK_STREAM,FD_CONNECT|FD_WRITE|FD_READ|FD_CLOSE);
   CltSkt.SetSockOpt(SO_RCVTIMEO,&TimeOut,sizeof(TimeOut));
   CltSkt.Connect(buff,serverport);
}
不知哪里出了问题。请教诸位了!

解决方案 »

  1.   

    CltSkt.m_hSocket = INVALID_SOCKET;
    是阻塞 还是非阻塞的?  有点糊涂
      

  2.   

    连接超时不是这样设置的。
    应该在connent之前调用 WSA。。
    函数,让socket变成非阻塞的。然后自己处理连接超时消息(到一定时间没有收到连接成功)
      

  3.   

    问题算是解决了吧,小结一下,以供参考。可以使用CAsyncSocket类中的OnConnect(int nErrorCode)函数
    如果是超时的话,回返WSAETIMEDOUT (值为10060),可通过对nErrorCode进行判断来做出对用户提示超时信息。
    但是此方法的返回时间无法设置,大概在20秒左右。还可以通过一下步骤:
    1,设置为非阻塞套接字 ; 
    2,connect, ;
    3,select判断超时。
    由于CAsyncSocket本身即为非阻塞套接字,所以只需在正常的connect语句后面添加select的判断语句来确定是否超时。
    CAsyncSocket  sock;
    struct   timeval   tmo   ;  
    fd_set   r;  
    FD_ZERO(&r);  
    FD_SET(sock.m_hSocket,   &r);  
    tmo.tv_sec   =   3;   //连接超时3秒  
    tmo.tv_usec  =   0;  
    ret  =  select(0, 0, &r, 0, &tmo);

    通过参考MSDN的select函数的返回值的说明:The select function returns the total number of socket handles that are ready and contained in the FD_SET structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred.
    可知,当ret==0时超时。此外还有一种方法:
    int   TimeOut=6000;   //设置发送超时6秒  
      if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char   *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){  
      return   0;  
      }  
      TimeOut=6000;//设置接收超时6秒  
      if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char   *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){  
      return   0;  
      }   
    使用setsockopt函数需要使用socket2
    问题是我用的是socket2  但是没有成功实现这种方法。
      

  4.   

    看CAsyncSocket的成员BOOL AsyncSelect(
       long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE 
    );在这里注册 FD_CONNECT事件。然后你调用connect ,connect就是非阻塞的。不调用这个还是阻塞的。
    之后等待OnConnect,这个就是连接成功的时候回掉的函数。