Как можно надежно обнаружить разрыв TCP-сокета с помощью MsgWaitForMultipleObjects?

Twisted включает реактор, реализованный поверх MsgWaitForMultipleObjects. По-видимому, у реактора есть проблемы с надежным обнаружением окончания TCP-соединения, по крайней мере, в случае, когда аналог посылает несколько байт, а затем быстро закрывает соединение. Похоже, происходит следующее:

  1. Реактор вызывает MsgWaitForMultipleObjects с некоторыми дескрипторами сокетов и QS_ALLINPUT.
  2. Вызов завершается и указывает, что хэндл сокета в этом состоянии (то есть имеет байты, ожидающие чтения, и был закрыт peer) активен.
  3. Реактор отправляет это уведомление в общую реализацию TCP.
  4. Реализация TCP считывает доступные байты из сокета. Есть несколько, они доставляются в код приложения.
  5. Управление возвращается реактору, который в итоге снова вызывает MsgWaitForMultipleObjects.
  6. MsgWaitForMultipleObjects больше никогда не указывает, что хэндл активен. Реализация TCP никогда больше не смотрит на сокет, поэтому она никогда не может определить, что соединение закрыто.

Это создает впечатление, что MsgWaitForMultipleObjects является механизмом уведомления, срабатывающим по краям. В документации MSDN говорится:

Waits until one or all of the specified objects are in the signaled state
or the time-out interval elapses.

Это не похоже на edge-triggering. Это похоже на триггер уровня.

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

Дополнение В документации MSDN для WSAEventSelect объясняется, что здесь происходит, в том числе указывается, что FD_CLOSE - это в основном одноразовое событие. После того, как оно прозвучало один раз, вы больше никогда его не получите. Это в какой-то мере объясняет, почему в Twisted есть эта проблема. Тем не менее, мне все еще интересно узнать, как эффективно использовать MsgWaitForMultipleObjects, учитывая это ограничение.

6
задан Jean-Paul Calderone 29 September 2011 в 16:08
поделиться