Последовательный порт через IOCP - PullRequest
2 голосов
/ 23 марта 2009

Можно ли использовать порты завершения ввода-вывода для последовательного ввода-вывода? В соответствии с Windows через C / C ++ это намекает на то, что это возможно, и приводит пример использования IOCP с физическими файлами, показывающий работу с CreateFile, ReadFile, WriteFile и т. Д. Однако может ли это на самом деле работать с последовательными коммуникациями - кто-нибудь это работает?

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

1 Ответ

3 голосов
/ 17 апреля 2009

Да, использование портов завершения ввода / вывода для последовательного ввода / вывода работает нормально. Для создания дескриптора файла для последовательного порта, подходящего для IOCP, требуется некоторая настройка. Но как только настройка завершена, вы можете выполнять асинхронные операции ReadFile() и WriteFile(), как с обычными файловыми дескрипторами и дескрипторами сокетов.

Настройка в основном:

  1. Открытый последовательный порт с CreateFile() передачей значения FILE_FLAG_OVERLAPPED в качестве параметра dwFlagsAndAttributes.
  2. Измените состояние последовательного порта, используя GetCommState() и SetCommState(). Делайте это так же, как если бы вы не использовали IOCP.
  3. Используйте GetCommTimeouts() и SetCommTimeouts(), чтобы отключить общее время ожидания для операций чтения, поскольку обычно не имеет смысла устанавливать время ожидания для асинхронных операций. (Вместо этого вы бы явно вызвали CancelIO() для отмены операции чтения.) Отключение общего тайм-аута выполняется путем установки нулевых полей ReadTotalTimeoutMultiplier и ReadTotalTimeoutConstant структуры COMMTIMEOUTS.

Теперь вы можете использовать дескриптор с IOCP так же, как вы это делаете с обычными файловыми дескрипторами и дескрипторами сокетов. То есть присоедините дескриптор к порту завершения, используя CreateIoCompletionPort(), инициируйте операции ввода-вывода с помощью ReadFile() или WriteFile(), используя структуру OVERLAPPED, завершите удаление из очереди, завершили сбой или отменили операции из порта завершения, используя функцию GetQueuedCompletionStatus().

Дополнительные события, специфичные для последовательного порта, также могут быть получены асинхронно с помощью функции WaitCommEvent().

...