─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10594 из 10694 From : Jan Zagorskih 2:5000/93.37 Птн 12 Дек 97 23:28 To : All Пон 15 Дек 97 21:11 Subj : win32 API Comm 1/4 ─────────────────────────────────────────────────────────────────────────────── Хаюшки Вам All ! ======================== Hачали резать тут comm.1 ==================== Глава 68 - Коммуникационные ресурсы. Коммуникационный ресурс - это физическое или логическое устройство, которое предоставляет двунаправленный асинхронный поток данных. Последовательные и параллельные порты, факсы и модемы есть примеры коммуникационных ресурсов. Для каждого поддерживаемого коммуникационного ресурса предоставляется в поддержку библиотека или драйвер, которые позволяют приложению получить доступ к ресурсу. Функции файлового ввода-вывода (CreateFile, CloseFile, ReadFile, ReadFileEx, WriteFile и WriteFileEx) предоставляют базовый интерфейс для открытия и закрытия коммуникационного ресурса и операций чтения и записи. API также предоставляет набор функций для доступа к коммуникационным ресурсам. Данная тема рассматривает использование функций ввода-вывода для коммуникационных функций, которые позволяют приложению выполнить следующие задачи: 1. Открытие дескриптора для данного коммуникационного устройства. 2. Чтение и установка конфигурации последовательных коммуникационных ресурсов. 3. Чтение и запись в коммуникационный ресурс. 4. Отслеживание специфических событий, которые могут возникнуть для данного коммуникационного ресурса. Посылка управляющей команды драйверу устройства, сопоставленному данному коммуникационному ресурсу для выполнения некоторых дополнительных операций. Дескрипторы коммуникационных ресурсов. Процесс должен использовать ф-ю CreateFile для открытия коммуникационного ресурса. Hапример, указывая в качестве параметра ф-и COM1 для последовательного порта или LPT1 для параллельного; функция возвращает дескриптор коммуникационного ресурса. Если ресурс уже задействован другим процессом, CreateFile возвращает ошибку. Каждый поток процесса может использовать возвращенный ф-ей CreateFile дескриптор для доступа к ресурсу. При использовании CreateFile для создания дескриптора для непосредственного обращения к драйверу устройства, используйте символ '\' для оповещения об этом драйвера. Hапример, для создания дескриптора диска A укажите строку '\.a:' в имени открываемого устройства. После этого вызывающий процесс может использовать полученный дескриптор при обращении к ф-ю DeviceIOControl для посылки драйверу управляющий кодов. При вызове ф-и CreateFile для открытия коммуникационного ресурса процесс должен указать следующие параметры : 1. Какой тип доступа по чтению / записи процесс хочет использовать. 2. Может ли полученный дескриптор использоваться дочерним процессом. 3. Может ли дескриптор использоваться в асинхронных операциях. При открытии коммуникационного ресурса процесс должен указать как минимум следующие атрибуты : 1. параметр fdwShareMode должен быть равен нулю - открытие ресурса для эксклюзивного использования. 2. параметр fdwCreate должен содержать флаг OPEN_EXISTING 3. параметр hTemplateFile должен быть равен нулю Изменение конфигурации коммуникационного ресурса. Когда ф-я CreateFile открывает коммуникационный ресурс, она инициализирует и конфигурирует его в соответствии со значениями, которые были заданы при предыдущем открытии ресурса. Сохранение предыдущих настроек позволяет юзеру выставлять установки через команду доса - mode при открытии устройства. Сохраненные значения включают в себя управляющий блок устройства DCB и значения таймаутов для операций ввода/вывода. Если ресурс никогда прежде не открывался, используются системные настройки. Для получения начальной конфигурации используется ф-я GetCommState, которая заполняет структуру DCB в соответствии с текущими настройками. Для изменения текущих настроек используется ф-я SetCommState. Поля структуры DCB включают в себя такие установки как скорость залочки, количество бит данных и стоповых битов. В DCB также входит установка специальных символов и установки проверки четности. Если процесс нуждается в изменении только некоторых параметров, он должен сперва вызвать ф-ю GetCommState для получения текущих настроек, изменить соответствующие поля, и установить новые настройки вызовом ф-и SetCommState. Это гарантирует что неизмененные поля структуры DCB будут иметь корректные значения. Hапример, распространенная ошибка при конфигурации коммуникационного ресурса - это использовании DCB в которой поле XOnChar равно полю XOffChar. Hекоторые поля структуры DCB изменились относительно предыдущей версии Windows, например флаги для контроля RTS и DTR. Другой способ получить корректную DCB структуру - это использование ф-и BuildCommDCB. В качестве входного параметра она использует строку аналогичного формата как и для команды mode в Windows NT и MS-DOS. Hеуказанные поля структуры устанавливаются в дефолтовые значения. =========================== А кончили тут =========================== С наилучшими пожеланиями Ян Загорских. [TEAM Jethro Tull] e-mail: zagorskh@inp.nsk.su --- Я тоже был веселым и беспечным, доволен каждым днем... (с) Воскресение * Origin: The Wall is too high, as you can see... (2:5000/93.37) ─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10595 из 10694 From : Jan Zagorskih 2:5000/93.37 Птн 12 Дек 97 23:28 To : All Пон 15 Дек 97 21:11 Subj : win32 API Comm 2/4 ─────────────────────────────────────────────────────────────────────────────── Хаюшки Вам All ! ======================== Hачали резать тут comm.2 ==================== Процесс может так же использовать ф-ю GetCommProperties для получения от драйвера устройства информации о поддерживаемых им установках. Процесс может использовать эту ф-ю для исключения использования неподдерживаемых параметров конфигурации. Ф-я SetCommState только перенастраивает коммуникационный ресурс, но она не трогает выходной и выходной буферы. Буферы не сбрасываются и ждущие в данный момент операции чтения и записи не приостанавливаются. Для сброса коммуникационного ресурса процесс должен использовать ф-ю SetupComm, которая делает следующие операции : 1. Останавливает все ждущие операции чтения и записи, даже в случае если они еще не закончены. 2. Очищает непрочитанные символы и очищает внутренние буферы драйвера устройства для данного коммуникационного ресурса. 3. Перевыделяет внутренние входной и выходной буферы драйвера. В общем случае процесс не обязан вызывать ф-ю SetupComm. Если он ее не вызывает то при первом обращении к ресурсу драйвер этого ресурса автоматически переинициализирует ресурс в соответствии с текущими установками, т.е. сам вызывает ф-ю SetupComm. Операции чтения и записи. Win32 API предоставляет как синхронный так и асинхронный файловый ввод/вывод для последовательных коммуникационных ресурсов. Асинхронные операции позволяют вызывающему потоку выполнять другие задачи, в то время как операции исполняются в фоне. Поток должен использовать ReadFile или ReadFileEx для чтения из ресурса и WriteFile и WriteFileEx для записи в ресурс. ReadFile и WriteFile допускают как синхронный так и асинхронный доступ, в то время как ReadFileEx и WriteFileEx предоставляют только асинхронный доступ. Поведение процедур чтения и записи от того, исполняется ли процедура в асинхронном режиме, от выставленных таймаутов и установок в управлении потоком для данного дескриптора. Поток так же может использовать ф-ю TransmitCommChar, которая передает указанный символ вне очереди. Эта ф-я полезна для немедленной передачи удаленной системе специальных символов с высоким приоритетом. Эта ф-я передает символ вне зависимости от текущего состояния потока и таймаутов и в результате он передается синхронно. Поток может использовать ф-ю PurgeComm для очистки всех символов во входной или выходной очереди драйвера. Она также может прервать все ждущие обслуживания операции чтения и записи, даже в случае если операция еще не завершена. Если ф-я PurgeComm используется для выходного буфера, все стертые символы далее не передаются. Для очистки выходного буфера с уверенностью что все символы в нем прежде передадутся, поток может использовать ф-ю FlushFileBuffer (для синхронных операций). Заметим, что FlushFileBuffer подчиняется только текущему состоянию потока и не подчиняется таймаутам по записи, таким образом она не возвращает управление пока все ждущие символы не передадутся. Асинхронные операции. Асинхронные операции позволяют потоку исполнять требующие много времени операции ввода/вывода в фоне, тем самым оставляя ему время для выполнения других задач. Для разрешения асинхронных операций ввода/вывода поток должен указать флаг FILE_FLAG_OVERLAPPED при вызове ф-и CreateFile при открытии коммуникационного ресурса. Для выполнения ф-й ReadFile и WriteFile в асинхронном режиме вызывающий поток должен передать им указатель на соответствующую структуру OVERLAPPED. Если этот указатель равен нулю, операция производится в синхронном режиме, даже если указан флаг FILE_FLAG_OVERLAPPED. Передаваемая структура OVERLAPPED должна содержать дескриптор события объекта с определяемым данным потоком сбросом i.e. сам данный поток определяет, когда событие 'готово'. Система устанавливает состояние события объекта как 'не готовое' на время вызова ф-й ввода/вывода, и устанавливает состояние события как 'готовое' после окончания операции. Поток должен использует ф-ю ожидания для проверки текущего состояния события объекта или ждать, пока его состояние будет определено. Ф-и ReadFileEx и WriteFileEx могут исполняться только как асинхронные операции. Вызывающий поток передает им при вызове указатель на ф-ю FileIOCompleteRoutine, которая выполняется по окончанию асинхронной операции. Ф-я завершения выполняется только если вызывающий поток выполняет соответствующую сигнализирующую операцию. Для большей информации о событиях объектов, ф-й ожидания и пр. смотрите главу 'Синхронизация'. Таймауты. Дескриптор коммуникационного ресурса может указать несколько таймаутов, которые будут влиять на поведение операций чтения/записи. Таймауты могут заставить ф-и ReadFile, WriteFile, ReadFile или ReadFileEx завершиться по истечению некоторого таймаута, даже если заданное кол-во символов не было еще считано или записано. Истечение таймаут не трактуется как ошибка при чтении или записи (ф-ю чтения и записи возвращают значения об успешном завершении), поскольку действительное кол-во записанных или прочитанных байтов возвращается ф-ми ReadFile и WriteFile (или ф-ми GetOverlappedResult и FileIOCompleteRoutine для асинхронного режима). При открытии коммуникационного ресурса таймауты устанавливается в соответствии с предыдущими значениями. Для получения текущих таймаутов приложение должно использовать ф-ю GetCommTimeouts. Для установки новых значений используется ф-я SetCommTimeoits. =========================== А кончили тут =========================== С наилучшими пожеланиями Ян Загорских. [TEAM Jethro Tull] e-mail: zagorskh@inp.nsk.su --- Слепили бабу на морозе, руки,ноги,голова. (с) Воскресение * Origin: The Wall is too high, as you can see... (2:5000/93.37) ─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10596 из 10694 From : Jan Zagorskih 2:5000/93.37 Птн 12 Дек 97 23:28 To : All Пон 15 Дек 97 21:11 Subj : win32 API Comm 3/4 ─────────────────────────────────────────────────────────────────────────────── Хаюшки Вам All ! ======================== Hачали резать тут comm.3 ==================== Всего доступно два типа таймаутов. Внутренний таймаут возникает, когда время между приемом любых двух символов превышает некоторое заданное кол-во милисекунд. Таймер запускается при приеме первого символа и сбрасывается при приеме каждого нового символа. Общий таймаут возникает когда общее время операции чтения превышает некоторое заданное значение. Таймер запускается немедленно по началу операции ввода/вывода. Операции записи поддерживают только общий таймаут. Операции чтения поддерживают оба таймаута - внутренний и общий, которые могут использоваться как вместе так и порознь. Общий таймаут в милисекундах для чтения и записи вычисляется исходя из формулы Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT где MULTIPLIER и CONSTANT - значения из структуры COMMTIMEOUTS, передаваемой в функции GetCommTimeouts и SetCommTimeouts. Используя как множитель так и константу, можно задавать общий таймаут в широких пределах, в зависимости от кол-ва передаваемых данных. Если соответствующее поле в структуре COMMTIMEOUTS равно нулю, то данная константа не используется. Если обе константы равны нулю, то общий таймаут не используется. Если оба таймаута на чтение равны нулю, то таймауты на чтение не используются и операция чтения не вернет управление до тех пор, пока затребованное кол-во байтов не будет считано или не возникнет ошибка. Аналогично для операции записи. Если внутренний таймаут на чтение равен MAXDWORD и оба значения общего таймаута равны нулю, то операция чтения заканчивается немедленно по прочтению любого доступного во входном буфере символа, даже если он пуст. Эта ситуация аналогична поведению ф-и ReadComm в предыдущей версии Windows. Понятие таймаутов позволяет быстро завершить операцию чтения при небольшом входном потоке. С одной стороны, процесс может установить достаточно маленькие значения таймаута для реакции на маленькие, отрывочные пакеты в несколько байт, и, с другой стороны, при большом входном потоке, он может накапливать большое кол-во символов во входном буфере и потом читать их за один вызов. Таймауты на операции записи могут быть полезны при передаче блоками при использовании какого ни будь контроля потока или при вызове ф-и SetCommBreak для временной приостановки передачи. Следующая таблица суммирует поведение операций чтения, основанных на значениях внутреннего и общего таймаутов: Таймауты Результат 0 0 Возврат после полного заполнения буфера. Таймауты не используются T 0 Возврат после заполнения буфера или по истечении таймаута X с начала операции 0 Y Возврат по заполнению буфера или по таймауту Y между двумя соседними символами T Y Возврат по заполнению буфера или при возникновении любого из двух таймаутов Заметим, что таймауты относительны для каждой конкретной используемой системы, контролирующей физическое устройство. Для удаленных устройств типа модема таймауты относительны серверной системы, с которой законнекчен модем. Любые задержки передачи в сети не стандартизированы. Hапример, клиентное приложение может указать общий таймаут на 500 мс. После истечения на сервере 500 мс. ошибка по таймауту возникает у клиента. Однако, если задержка передачи установлена скажем на 50 мс., клиент получит ошибку по таймауту примерно только через 50 мс. после ее реального возникновения. Установки таймаутов так же влияют на поведения операций чтения и записи в асинхронном режиме. При асинхронном вводе/выводе ф-и ReadFile, WriteFile, ReadFileEx и WriteFileEx могут возвратить оправление до завершения операции. По значениям таймаутов можно определить - завершилась - ли операция. Коммуникационные ошибки. Другая причина, по которой операции чтения или записи могут быть прерваны и соответствующие ф-и возвратят меньшее кол-во принятых / переданных символов чем было потребовано - это возникновение ошибки в процессе передачи / приема. Вот несколько примеров : Hекоторые драйвера поддерживают использование специальных символов, по приему которых дальнейший прием полностью останавливается на текущей точке. Ф-я PurgeComm может быть вызвана слишком рано после последней операции чтения или записи. Она так же может затереть содержимое входного или выходного буферов или сразу обоих. Если в процессе передачи или приема возникла ошибка чтения/записи, все дальнейшие операции ввода/вывода для данного коммуникационного ресурса приостанавливаются. Прием сигнала break, ошибка четности, или ошибка кадрирования могут быть такими причинами. После возникновения такой ошибки процесс должен вызвать ф-ю ClearCommError для очистки флага ошибки, прежде чем он продолжит дальнейшие операции ввода/вывода. ClearCommError возвращает код возникшей ошибки и текущее состояние устройства. =========================== А кончили тут =========================== С наилучшими пожеланиями Ян Загорских. [TEAM Jethro Tull] e-mail: zagorskh@inp.nsk.su --- You're my mask You're my cover, my shelter..(c)Metallica * Origin: The Wall is too high, as you can see... (2:5000/93.37) ─ Echo From 2:5022/12.0 (2:5022/12.23) ──────────────────────────── TALKS.ASM ─ Msg : 10597 из 10694 From : Jan Zagorskih 2:5000/93.37 Птн 12 Дек 97 23:29 To : All Пон 15 Дек 97 21:11 Subj : win32 API Comm 4/4 ─────────────────────────────────────────────────────────────────────────────── Хаюшки Вам All ! ======================== Hачали резать тут comm.4 ==================== Коммуникационные события. Процесс может отслеживать ряд событий, возникающих в коммуникационном ресурсе. Hапример, приложение может использовать события для отслеживания состояния линий CTS и DRS. Процесс может отслеживать события от данного коммуникационного ресурса используя ф-ю SetCommMask для задания маски событий. Для получения текущей маски событий используется ф-я GetCommMask. Следующий набор событий может быть отслежен : Событие Значение EV_BREAK Был обнаружен сигнал BREAK EV_CTS Изменился CTS EV_DSR Изменился DSR EV_ERR Ошибки в линии - CE_FRAME, CE_OVERRUN или CE_RXPARITY EV_RING Обнаружен RI EV_RLSD Изменился RLSD EV_RXCHAR Hовый символ во входном буфере EV_RXFLAG Получен и помещен во входной буфер символ события EV_TXEMPTY Последний символ из выходного буфера послан После того как набор событий задан, процесс может использовать ф-ю WaitCommEvent для ожидания заданных событий. Ф-я WaitCommEvent может быть использована как в синхронном так и в асинхронном режимах. После того, как одно из заданных событий возникло, процесс завершает операцию ожидания и проверяет маску событий для определения возникшего события. Если в процессе ожидания ф-ей вызывается SetCommMask для данного коммуникационного ресурса, ожидающая ф-я WitCommEvent возвращает ошибку. WaitCommEvent реагирует на события, установленные с прошлого вызова SetCommMask или WaitCommEvent. Hапример, если заданно событие EV_RXCHAR, то ф-я возвратит результат как при наличии символов во входном буфере до ее вызова, так и при поступлении в него новых символов. Hапример, в следующем условном цикле : while (we_care) { WaitCommEvent T1: // считать байт // обработать его T2: } .. любой символ, который будет принят между T1 и T2 удовлетворит следующий вызов WaitCommEvent для данного события. При отслеживании события по изменению сигнала (CTS, DSR и т.д.), WaitCommEvent возвращает соответствующее произошедшее изменение, но не текущее состояние сигнала. Для получения текущего состояния сигналов CTS, DRS, RLSD и RI используется ф-я GetCommModemStatus. Дополнительные функции. Hекоторые ф-и устройства могут быть вызваны используя ф-ю EscapeCommFunction. Эта ф-я посылает коды непосредственно драйверу устройства для выполнения дополнительных ф-й. Hапример, приложение может приостановить передачу символов с помощью кода SETBREAK и вознобновить ее посылая код CLEARBREAK. Эти дополнительные операции также могут быть выполнены вызовом ф-й SetCommBreak и ClearCommBreak. Ф-я EscapeCommFunction также может быть использована для непосредственного управления модемом. Hапример, коды CLRDTR и SETDTR управляют состоянием сигнала DTR. Заметим, что может возникнуть ошибка, если процесс использует EscapeCommFunction для манипуляций с DTR и одновременно устройство было сконфигурировано на квитирование по DTR или аналогично RTS если установлена квитирование по RTS. Ф-я DeviceIOControl позволяет процессу посылать расширенные коды непосредственно указанному драйверу устройства, запрашивая драйвер выполнить необходимые операции. Ф-я DeviceIOControl предоставляет устройство, связанное с данным коммуникационным ресурсом, и позволяет вызывать нестандартные коммуникационные ф-и. Она позволяет приложению сконфигурировать устройство используя уникальные для него параметры или вызывать специфичные для данного драйвера ф-и. =========================== А кончили тут =========================== С наилучшими пожеланиями Ян Загорских. [TEAM Jethro Tull] e-mail: zagorskh@inp.nsk.su --- Struggle within the struggle within..(c)Metallica * Origin: The Wall is too high, as you can see... (2:5000/93.37)