Бизнес-логика в Порте завершения ввода-вывода

У меня есть некоторые сомнения относительно порта завершения ввода-вывода, а также AcceptEx в winsock2

Пожалуйста, поправьте меня, если я ошибаюсь.

  1. AcceptEx - это перекрывающийся способ приема запросов или подключения. Однако, как указано в нескольких сообщениях на этом сайте, AcceptEx подвержен атаке DOS, если AcceptEx ожидает данные, но не отправляется подключенным клиентом. Итак, можно ли решить эту проблему, просто поставив 0 в dwReceiveDataLength?

  2. Кроме того, каковы преимущества возможности получать данные от клиента при принятии соответствующего подключения, а не получать данные позже с помощью AcceptEx?

  3. После приема соединений от противоположной конечной точки и связывания ее с портом завершения ввода-вывода запросы ставятся в очередь в порте завершения ввода-вывода как пакеты завершения, которые связаны с их соответствующим дескриптором. Рабочие потоки, которые блокируют порт завершения, будут разбужены в зависимости от NumberOfConcurrentThreads для обслуживания запросов. Итак, являются ли потоки в порту завершения потоками ввода-вывода?

  4. Итак, где мне реализовать бизнес-логику или операцию на сервере сокетов? Например, запрос от клиента, который отправляет числа на сервер для обработки, в то время как сервер действует как калькулятор, который в ответ возвращает вычисленный результат. Таким образом, можно ли реализовать эту логику в Порте завершения ввода-вывода?

  5. Если логика реализована в порте завершения ввода-вывода (когда потоки ввода-вывода (предполагается), которые активны в порте завершения ввода-вывода, выполняют WSARecv или WSASend)), будет ли блок потоки ввода-вывода в ожидании завершения расчета, что делает невозможным подключение, если все невыполненные задания выполнены?

ИЗМЕНИТЬ:

  • Например, после принятия клиентского сокета и добавления в очередь / связывания с портом завершения ввода-вывода (main_cpl_port) потоки, которые блокируют этот main_cpl_port вызовите GetQueuedCompletionStatus для удаления пакета завершения и последующего чтения данных в выделенный буфер. Перед тем, как какой-либо ответ будет записан обратно клиенту, буфер обрабатывается / анализируется на предмет «команды» (например: GoToCalculator, GoToRecorder).
  • Например, GoToCalculator отвечает за другие команды, связанные с расчетами.
  • В этом случае GoToCalculator на самом деле является еще одним портом завершения ввода-вывода, который обслуживает все запросы, связанные с вычислениями. Допустим, порт завершения называется calc_completion_port.
  • Таким образом, возможно ли, что пакет завершения из main_cpl_port будет отправлен в calc_completion_port для будущего ввода-вывода (отправка и recv) из клиентского сокета, который в настоящее время связан с main_cpl_port. Это то, для чего используется PostQueuedCompletionStatus?
  • Может ли сообщение, отправленное клиентом после отправки на calc_completion_port, потоки, которые блокируют этот порт завершения? Другими словами, как я могу перенаправить соединение на другой порт завершения с другого?

person vincent911001    schedule 10.03.2016    source источник


Ответы (1)


1) Избежать потенциальной атаки AcceptEx DOS легко, просто не выделяйте места для данных, и AcceptEx завершится, как только будет установлено соединение.

2) Использование AcceptEx означает, что вам не нужно иметь отдельный поток для запуска цикла приема. Это удаляет один поток из вашей системы и сокращает переключение контекста. Это особенно полезно, если вы слушаете несколько сокетов (разные порты / интерфейсы), так как каждому слушающему сокету потребуется свой собственный поток приема.

3) Да, рабочие потоки, которые вызывают GetQueuedCompletionStatus в IOCP, можно рассматривать как потоки ввода-вывода ...

4) Это зависит от обстоятельств. Я построил системы с отдельными пулами потоков ввода-вывода фиксированного размера, которые никогда не выполняют никаких блокирующих операций, и с отдельными расширяющимися пулами потоков, предназначенными для выполнения операций блокировки. Идея состоит в том, что это предотвратит блокировку всех потоков и предотвращение ввода-вывода ... Это требует, чтобы вы передавали рабочие элементы в другой пул потоков, и это вызывает ненужное переключение контекста и сложность, но это означает, что у вас всегда есть потоки для выполнения операций ввода-вывода (таких как обработка новых подключений по мере завершения AcceptEx) ... Этот вид дизайна использовался для хорошей работы, когда API-интерфейсы IOCP использовались для отмены отложенных операций, если запущенный поток затем завершился до завершения операции. Теперь, когда ОС изменила правила и ожидающие операции не отменяются, нет реальной причины, по которой у вас нет просто расширяющегося / сужающегося пула потоков ввода-вывода и вы не выполняете всю свою работу там ... Вам просто нужно отслеживать, как доступно много потоков и они создают / уничтожают потоки, поскольку вам нужно расширить / сузить свой пул ...

5) см. 4.

person Len Holgate    schedule 11.03.2016
comment
Привет, Лен, у меня мало сомнений в редактировании вопроса, надеюсь, ты сможешь пролить свет на это. Спасибо - person vincent911001; 25.03.2016
comment
IOCP могут использоваться для перекрывающегося ввода-вывода с помощью API, которые отправляют результаты в IOCP. Вот как работают WSARecv () и т. Д. Их также можно использовать программно как рабочую очередь с помощью PostQueuedCompletionStatus (). В любом случае завершения извлекаются с помощью GetQueuedCompletionStatus (). См. Здесь рабочий пример: serverframework.com/ < / а> - person Len Holgate; 25.03.2016