2008-11-07 8 views
7

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

первый шанс исключение:

первого шанса исключение в 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; 
    } 
+0

Это прослушивание выполняется только при запуске? Является ли порт привязанным к динамическому? Сколько портов вы слушаете в любой момент? – 2008-11-07 16:59:49

ответ

6

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

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

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

NetStat -an

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

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

0

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

1

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

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

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

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

+0

Переход на SOMAXCONN не помог, но это, безусловно, подсказка, которую я возьму с собой. LINGER не помог ни одному :-( – 2008-11-07 19:15:02

2

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

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

3

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