Исключение сокета: «Нет больше доступных конечных точек из сопоставителя конечных точек» - PullRequest
7 голосов
/ 07 ноября 2008

Я использую winsock и C ++ для настройки серверного приложения. У меня проблема в том, что вызов listen приводит к исключению из первого шанса. Я предполагаю, что обычно их можно игнорировать (?), Но я обнаружил, что у других возникает такая же проблема, из-за которой приложение время от времени зависает. Любая помощь будет принята с благодарностью.

Первое исключение:

Исключение первого шанса в 0x * 12345678 * в MyApp .exe: 0x000006D9: больше нет доступных конечных точек из преобразователя конечных точек.

Я нашел доказательства того, что это может быть вызвано сокетом. Код, с которым я работаю, выглядит следующим образом. Исключение происходит при вызове listen в пятой строке снизу.

  m_accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (m_accept_fd == INVALID_SOCKET)
  {
    return false;
  }

  int optval = 1;

  if (setsockopt (m_accept_fd, SOL_SOCKET, SO_REUSEADDR,
                  (char*)&optval, sizeof(optval)))
  {
    closesocket(m_accept_fd);
    m_accept_fd = INVALID_SOCKET;
    return false;
  }

  struct sockaddr_in  local_addr;
  local_addr.sin_family = AF_INET;
  local_addr.sin_addr.s_addr = INADDR_ANY;
  local_addr.sin_port = htons(m_port);

  if (bind(m_accept_fd, (struct sockaddr *)&local_addr,
           sizeof(struct sockaddr_in)) == SOCKET_ERROR)
  {
    closesocket(m_accept_fd);
    return false;
  }

  if (listen (m_accept_fd, 5) == SOCKET_ERROR)
  {
    closesocket(m_accept_fd);
    return false;
  }

Ответы [ 5 ]

6 голосов
/ 08 ноября 2008

На очень загруженном сервере у вас может не хватить сокетов. Возможно, вам придется настроить некоторые параметры TCPIP. Настройте эти два в реестре:

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
   MaxUserPort  REG_DWORD  65534 (decimal)
   TcpTimedWaitDelay REG_DWORD 60 (decimal)

По умолчанию задержка в несколько минут между освобождением сетевого порта (сокета) и его повторным использованием. Кроме того, в зависимости от версии ОС, в диапазоне, который будут использовать Windows, всего несколько тысяч. На сервере выполните это в командной строке:

netstat -an

и посмотрите на результаты (труба к файлу проще всего: netstat -an> netstat.txt). Если вы видите большое количество портов с 1025-> 5000 в состоянии задержки по времени, то это ваша проблема, и она решается путем настройки максимального пользовательского порта с 5000 до 65534 с помощью записи реестра выше. Вы также можете отрегулировать задержку, используя приведенную выше запись реестра, чтобы быстрее перезапускать порты.

Если это не проблема, то, скорее всего, проблема в количестве ожидающих соединений, которые вы установили в своем методе Listen ().

3 голосов
/ 13 марта 2009

Исходная проблема не имеет ничего общего с winsock. Все ответы выше НЕПРАВИЛЬНЫ. Игнорируйте исключение первого шанса, это не проблема вашего приложения, просто некоторая внутренняя обработка ошибок.

2 голосов
/ 08 ноября 2008

Вы действительно видите проблему, например, завершается ли программа из-за необработанного исключения?

Отладчик может распечатать сообщение, даже если нет проблем, например, см. здесь

1 голос
/ 07 ноября 2008

Э-э, может, это потому, что вы сильно ограничиваете максимальное количество входящих соединений?

listen (m_accept_fd, 5)
// Limit here       ^^^

Если вы допустите большее отставание, вы сможете решить вашу проблему. Используйте что-то вроде SOMAXCONN вместо 5.

Кроме того, если ваша проблема только при запуске сервера, вы можете отключить LINGER (SO_LINGER), чтобы предотвратить зависание соединений и блокирование сокета ...

0 голосов
/ 07 ноября 2008

Это не будет отвечать на ваш вопрос напрямую, но, поскольку вы используете C ++, я бы порекомендовал использовать что-то вроде Boost :: Asio для обработки кода вашего сокета. Это дает вам хорошую абстракцию по сравнению с Winsock API и должно упростить диагностику ошибок.

...