• Socket中如何设置连接超时(转载 可能用的到)



      设置connect的超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案。偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使那些想避免在套接字调用过程中被锁定的应用程序,采取一种有序的方式,同时对多个套接字进行管理"(《Windows网络编程技术》原话)。使用方法与解释请见《Windows网络编程技术》。
      在使用此函数前,需先将socket设置为非锁定模式,这样,在connect时,才会立马跳过,同时,通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系。再执行select则是真正的超时。

    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;
    }

  • 相关阅读:
    第八周学习进度
    《梦断代码》阅读笔记01
    冲刺记录一
    NABCD简介
    第七周学习进度
    《编程珠玑》阅读笔记03
    第六周学习进度
    数据库数据定期同步实现
    数据库之间的数据同步
    数据同步——otter
  • 原文地址:https://www.cnblogs.com/BoyeeStudio/p/425526.html
Copyright © 2020-2023  润新知