c - 无法设置套接字 connect() 调用的超时

标签 c sockets connection

我已经用 native 代码编写了客户端套接字程序,并在 Android 应用程序中使用它。当服务器不可用时与服务器建立连接时,我遇到一个奇怪的问题。

当服务器不可用时,客户端的 connect() 调用会被折腾,根本出不来。我试图在互联网上搜索这个问题。一些链接解释了这些步骤

  1. 将套接字设置为非阻塞模式
  2. 调用连接 - 如果连接成功则正常
  3. 否则将套接字设置回阻止模式。
  4. 设置用于写入集的套接字,并将其提供给 select() 并设置所需的超时。
  5. 如果选择输出时在写入集中设置了套接字,则连接成功或连接失败。

我尝试了这些步骤,但是无论服务器是否正在运行,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;
}

当服务器可用时,如果我使用阻塞的连接调用(不使用任何上述步骤),建立连接几乎不需要 1 秒。

当服务器可用时,如果我使用上述步骤进行连接,则如果我给 5 秒时间未建立连接,则会发生事件。事件select也没有等待5秒,立即返回值0。

请检查此代码,并让我知道在设置 connection() 调用超时时到底哪里出了问题。

任何建议或替代方法都值得赞赏。

谢谢。

最佳答案

使用警报来中断连接。这是示例代码

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

关于c - 无法设置套接字 connect() 调用的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12816921/

相关文章:

c# - SqlDataReader 和 SqlCommand

android - 如何使用特定的 bssid android 连接到 wifi?

c - OpenGLESv2 中的 glColor4f 相当于什么?

c - 并行点积,更多核心会使其变慢吗?

c - 初始化后无法将字符串放入数组中 - 使用适用于 ARM 的 TI 编译器 5.1.8 的 CCS 6

c - 在linux中创建socket和FD_SET后select总是返回1

sockets - TCP server socket编程为什么要得到两个文件描述符?

c++ - libclang/libtooling 处理或关闭所有错误输出

java - 检测损坏的 socket

http - 如何在 Windows 上解锁端口