【问题标题】:File descriptor returned from socket is larger than FD_SETSIZE从套接字返回的文件描述符大于 FD_SETSIZE
【发布时间】:2014-06-27 11:16:59
【问题描述】:

我有一个问题,返回的文件描述符会逐渐增加到大于FD_SETSIZE 的数字。

我的 tcp 服务器不断关闭,这需要我的客户端关闭套接字并重新连接。然后客户端将尝试通过调用socket 重新连接到服务器,以在调用connect 之前获取新的文件描述符。

但是,似乎每次我调用socket,返回的文件描述符都会增加,并且在一定时间后它变得大于FD_SETSIZE,这是我使用select 监控套接字的问题。

即使套接字已关闭,是否可以重用从socket 返回的第一个文件描述符用于connect 调用?还是有其他解决方法?

重新连接代码(循环直到连接):

int s = getaddrinfo(hostname, port, &hints, &result);    
if (s != 0) { ... HANDLE ERROR ...}
...
struct addrinfo *rp;
int sfd;
for (rp = result; rp != NULL; rp -> ai_protocol)
{
    sfd = socket( rp->ai_family, rp->ai_sockettype, rp->ai_addrlen);
    if (sfd >= 0)
    {
       int res = connect(sfd, rp->ai_addr, rp->ai_addrlen);
       if (res != -1)
       {
          _sockFd = sfd;
          _connected = true;
          break;   
       }
       else
       {
          close (sfd);
          break; 
       }
    } 
}
if (result != NULL)
{
    free(result);
}

读取消息代码:

if (_connected)
{
   ...
   retval = select(n, &rec, NULL, NULL, &timeout);
   if (retval == -1) 
   {
      ...
      _connected = false;
      close(_sockFd);      
   }
   else if (retval)
   {
      if (FD_ISSET(_sockFD, &rec) == 0)
      {
         ....
         return;
      }

      int count = read(...)

      if (count)
      {
         ....
         return;
      }
      else
      {
         ....
         _connected = false;
         close(_sockFd);
      } 
   }
}

【问题讨论】:

  • 贴出相关代码。你做错了什么。如果您真的要关闭套接字 fd,那么您应该在随后的打开时得到相同的。而且你不应该得到大于 FD_SETSIZE 的返回 FD,除非你明确设置你的进程来增加每个进程的默认 FD 数。

标签: c++ linux sockets tcp


【解决方案1】:

如果连接失败,您不会关闭套接字。所以它保持打开状态,占用一个 FD,所以下次调用 socket() 时,你会得到一个新的 FD。当 connect() 成功时,您也没有跳出循环,这是另一个泄漏。您也没有检查 read() 的结果是否为 -1。

【讨论】:

  • 连接时错过的中断是一个错字(对不起,我不得不手动跨代码输入)。连接失败后我会尝试添加关闭。
  • 是的,连接失败后的关闭修复了它!干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
  • 2015-08-11
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 2011-03-31
相关资源
最近更新 更多