У меня проблема с частью устаревшего кода на c ++ / winsock, который является частью многопоточного сервера сокетов. Приложение создает поток, который обрабатывает соединения от клиентов, которых обычно одновременно подключено несколько сотен. Обычно он работает без проблем в течение нескольких дней (непрерывно), а затем внезапно прекращает принимать подключения. Это происходит только в производстве, никогда не тестировать.
Он использует WSAEventSelect () для обнаружения сетевых событий FD_ACCEPT. (Упрощенный) код для обработчика соединения:
SOCKET listener;
HANDLE hStopEvent;
// ... initialise listener and hStopEvent, and other stuff ...
HANDLE hAcceptEvent = WSACreateEvent();
WSAEventSelect(listener, hAcceptEvent, FD_ACCEPT);
HANDLE rghEvents[] = { hStopEvent, hAcceptEvent };
bool bExit = false;
while(!bExit)
{
DWORD nEvent = WaitForMultipleObjects(2, rghEvents, FALSE, INFINITE);
switch(nEvent)
{
case WAIT_OBJECT_0:
bExit = true;
break;
case WAIT_OBJECT_1:
HandleConnect();
WSAResetEvent(hAcceptEvent);
break;
case WAIT_ABANDONED_0:
case WAIT_ABANDONED_0 + 1:
case WAIT_FAILED:
LogError();
break;
}
}
Из подробного ведения журнала я знаю, что при возникновении проблемы поток входит в WaitForMultipleObjects () и никогда не появляется, даже если есть клиенты, пытающиеся подключиться и ожидающие принятия. Условия WAIT_FAILED и WAIT_ABANDONED_x никогда не выполняются.
Хотя я не исключил проблему с конфигурацией на сервере или даже какую-то утечку ресурсов (ничего не могу найти), мне также интересно, не происходит ли диссоциация с событием, созданным WSACreateEvent (). 'из сетевого события FD_ACCEPT - вызывая его никогда не срабатывать.
Так, я что-то здесь не так делаю? Есть ли что-то, что я должен делать, а я нет? Или лучше? Буду признателен за любые предложения! Благодаря.
EDIT
Розетка - это неблокирующая розетка.
EDIT
Проблема решена с помощью подхода, предложенного Кипкеннеди (ниже). Изменил hAcceptEvent на событие автоматического сброса и удалил вызов WSAResetEvent (), который больше не нужен.