rt

解决方案 »

  1.   

    在recv之前调用. 可以控制超时. 如果直接recv的话, 对方没有数据过来. 会长时间阻塞.
      

  2.   

    多路复用,是socket提供的一个比较有效的socket管理模型
      

  3.   


    WSADATA wsd;
    SOCKET cClient;
    int ret;
    struct sockaddr_in server;
    hostent *host=NULL;if(WSAStartup(MAKEWORD(2,0),&wsd)){return 0;}
    cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(cClient==INVALID_SOCKET){return 0;}
    //set Recv and Send time out
    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;
    }
    //设置非阻塞方式连接
    unsigned long ul = 1;
    ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
    if(ret==SOCKET_ERROR)return 0;//连接
    server.sin_family = AF_INET;
    server.sin_port = htons(25);
    server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);
    if(server.sin_addr.s_addr == INADDR_NONE){return 0;}connect(cClient,(const struct sockaddr *)&server,sizeof(server));//select 模型,即设置超时
    struct timeval timeout ;
    fd_set r;FD_ZERO(&r);
    FD_SET(cClient, &r);
    timeout.tv_sec = 15; //连接超时15秒
    timeout.tv_usec =0;
    ret = select(0, 0, &r, 0, &timeout);
    if ( ret <= 0 )
    {
    ::closesocket(cClient);
    return 0;
    }
    //一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
    unsigned long ul1= 0 ;
    ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
    if(ret==SOCKET_ERROR){
    ::closesocket (cClient);
    return 0;
    }
      

  4.   

    时间驱动啦,,等有你SELECT的事件发生时就放行进入下一步,否则堵塞。
    发生的事件可能是有数据、发、超时等,看你自己的定义(参数指定)。
      

  5.   

    socket管理的一个模型,同unix下一样
      

  6.   

    select可以I/O复用,它最大的优势是能同时判断多个套接口的多种I/O状态。一次成功返回表明至少有一个套接口满足I/O的状态要求。