使用select()来检测连接关闭

时间:2015-01-03 22:11:53

标签: select asyncsocket

如其他帖子中所述,我正在尝试在套接字编程中使用select()来检测已关闭的连接。请参阅以下代码,尝试通过select()检测已关闭的连接,然后检查recv()是否返回0.在while循环启动之前,已经有两个已建立的TCP连接。在我们的对照实验中,第一个连接总是在大约15秒后关闭,第二个连接大约在30秒后关闭。

理论上(正如其他人所描述的),当它们被关闭时,select()应该返回(在我们的情况下是两次),这允许我们检测两个关闭事件。我们面临的问题是select()现在只返回一次而不再返回,这使我们只能检测第一个连接关闭事件。如果一个IP的代码可以正常工作,但不能用于两个或多个连接。

任何人都有任何想法或建议?感谢。

while (1)
   {
      printf("Waiting on select()...\n");
      if ((result = select(max + 1, & readset, NULL, NULL, NULL)) < 0)
      {
         printf("select() failed");
         break;
      }
      if (result > 0)
      {
        i=0;
        while(i<max+1) 
        {
          if (FD_ISSET(i, &readset)) 
          { 
            result = recv(i, buffer, sizeof(buffer), 0);
            if (result == 0) 
               {
                  close(i);
                  FD_CLR(i, &readset);
                  if (i == max)
                  {
                     max -= 1;
                  }
               }
          }
      i++;
        }
     }
  }

1 个答案:

答案 0 :(得分:0)

select()修改readset以删除不可读的套接字。每次拨打select()时,都必须重置readset并填写您要测试的最新活动套接字列表,例如:

fd_set readset;
int max;

while (1)
{
    FD_ZERO(&readset);
    max = -1;

    // populate readset from list of active sockets...
    // set max according...

    printf("Waiting on select()...\n");
    result = select(max + 1, &readset, NULL, NULL, NULL);
    if (result < 0)
    {
       printf("select() failed");
       break;
    }

    if (result == 0)
        continue;

    for (int i = 0; i <= max; ++i)
    {
        if (FD_ISSET(i, &readset)) 
        { 
          result = recv(i, buffer, sizeof(buffer), 0);
          if (result <= 0) 
          {
              close(i);
              // remove i from list of active sockets...
          }
      }
   }
}