Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无法设置套接字连接()调用的超时_C_Sockets_Connection - Fatal编程技术网

C 无法设置套接字连接()调用的超时

C 无法设置套接字连接()调用的超时,c,sockets,connection,C,Sockets,Connection,我已经用本机代码编写了客户端套接字程序,并在android应用程序中使用它。当服务器不可用时,我在连接服务器时面临一个奇怪的问题 当服务器不可用时,客户端connect()调用将被抛出,根本不会出现。我试着在网上搜索这个。一些链接正在解释这些步骤 将套接字设置为非块模式 调用连接-如果连接成功,则可以 否则,将套接字设置回块模式 为write set设置套接字,并在需要超时的情况下将其指定给select() 如果select输出时在写集中设置了套接字,则连接成功或连接失败 我尝试了这些步骤,但无

我已经用本机代码编写了客户端套接字程序,并在android应用程序中使用它。当服务器不可用时,我在连接服务器时面临一个奇怪的问题

当服务器不可用时,客户端connect()调用将被抛出,根本不会出现。我试着在网上搜索这个。一些链接正在解释这些步骤

  • 将套接字设置为非块模式
  • 调用连接-如果连接成功,则可以
  • 否则,将套接字设置回块模式
  • 为write set设置套接字,并在需要超时的情况下将其指定给select()
  • 如果select输出时在写集中设置了套接字,则连接成功或连接失败 我尝试了这些步骤,但无论服务器是否正在运行,select()调用总是只显示超时。我需要你的帮助来解决这个问题

    这是我正在使用的代码的一部分

    bool SocketConnect()
    {
       ... Creating the socket ....
    
       int opts;
       if( (opts = fcntl(clientsocket,F_GETFL) < 0 )
       {
           return false;
       }
    
       // setting socket to non-block mode
       if( fcntl(clientsocket,opts | O_NONBLOCK) < 0 )
       {
          return false;
       }
    
       //calling connect
       int ret = connect(clientsocket,(const sockaddr*)&serveraddr,sizeof(serveraddr));
       if( ret < 0 )
       {
           if( errno != EINPROGRESS )
           {
              return false;
           }
       }
    
       if( ret == 0 )
       {
          //connection successful set the socket to block mode
          fcntl(clientsocket,F_SETFL,opts);
          return true;
       }
    
       //set the socket to block mode
       if( fcntl(clientsocket,F_SETFL,opts) < 0 )
       {
          return false;
       }
    
       fd_set writeset;
       FD_ZERO(&writeset);
       FD_SET(clientsocket,&writeset);
    
       timeval val.
       val.tv_sec = 5;
       val.tv_usec = 0;
    
       int sret = select(clientsocket+1,NULL,&writeset,NULL,&val);
       if( sret > 0 )
       {
          if( FD_ISSET(clientsocket,&writeset) )
          {
              fcntl(clientsocket,F_SETFL,opts);
              return true;
          }
       }
    
       return false;
    }
    
    bool SocketConnect()
    {
    …正在创建套接字。。。。
    int opts;
    if((opts=fcntl(clientsocket,F_GETFL)<0)
    {
    返回false;
    }
    //将套接字设置为非块模式
    if(fcntl(客户端套接字,选择非块)<0)
    {
    返回false;
    }
    //呼叫连接
    int ret=connect(clientsocket,(const sockaddr*)和serveraddr,sizeof(serveraddr));
    如果(ret<0)
    {
    if(errno!=EINPROGRESS)
    {
    返回false;
    }
    }
    如果(ret==0)
    {
    //连接成功将套接字设置为块模式
    fcntl(客户端套接字、F_SETFL、opts);
    返回true;
    }
    //将套接字设置为块模式
    如果(fcntl(客户端套接字、F_SETFL、opts)<0)
    {
    返回false;
    }
    fd_集写集;
    FD_ZERO(写入集和写入集);
    FD_集(clientsocket和writeset);
    蒂梅瓦尔。
    val.tv_sec=5;
    val.tv_usec=0;
    int sret=select(clientsocket+1,NULL,&writeset,NULL,&val);
    如果(sret>0)
    {
    if(FD_ISSET(clientsocket和writeset))
    {
    fcntl(客户端套接字、F_SETFL、opts);
    返回true;
    }
    }
    返回false;
    }
    
    当服务器可用时,如果我使用阻塞连接调用(不使用上述任何步骤),建立连接几乎不需要1秒

    当服务器可用时,如果我使用上述步骤进行连接,那么如果我给事件5秒的时间连接未建立。事件选择也未等待5秒,立即返回值0

    请查看此代码,并让我知道在设置connection()调用的超时时到底哪里出错了

    如有任何建议或替代方法,敬请谅解


    谢谢。

    如果您处于非阻塞模式,我看不出您在等待连接完成


    另外,我会问,在连接建立之前,应用程序应该做些什么吗?如果是这样,我会考虑使用pPults之类的东西将SockCuffic函数重新配置到一个单独的线程中。如果应用程序的行为仅仅依赖于客户端连接,我会考虑将套接字从N转换为N。在连接之前从阻塞到阻塞,并在SocketConnect中保留连接调用。

    使用报警中断连接。下面是示例代码

    #define CONNECT_TIMEOUT 4
    
    static void AlarmHandler(int sig)
    {
    sTimeout = 1; 
    }
    .
    .
    .
    signal(SIGALRM, AlarmHandler); 
    sTimeout = 0; 
    alarm(CONNECT_TIMEOUT); 
    if ( connect(sock, (struct sockaddr *) &server, sizeof(server)) ) 
    { 
    if ( sTimeout ) {
    NSLog(@"timeout connecting stream socket"); //If connect will remain blocked for 4 seconds after 4 seconds this condition will be triggered
    }
    }
    

    我发现connect()上的linux文档完全错了。在非阻塞connect()上发生某些事情时,您不会得到写入事件,而是会得到读取事件——即使这样,我似乎还记得一些没有发出读取事件的极端情况。(请记住,超时的TCP SYNs可能需要几分钟,超时的ARP请求也可能需要几秒钟-在许多情况下,TCP/IP堆栈无法对connect()提供近乎即时的反馈)他在非阻塞模式下调用connect(),这会导致connect()立即返回,并延迟连接完成(或超时)选择()调用Hi感谢您的响应..我用其他方法解决了这个问题。现在我使用setsockopt设置读写操作的超时。现在,如果服务器在超时内没有响应,连接将出现…:-)