Справочник программиста на персональном компьютере фирмы IBM. Ввод/вывод - Получение данных

ОГЛАВЛЕНИЕ

     7.1.7 Получение данных.


   Коммуникационная  программа готова принимать данные как только
инициализирован коммуникационный порт [7.1.2] и установлена связь
с  удаленной станцией [7.1.5].  Прием данных никогда полностью не
отделен от передачи данных,  поскольку  программе  может потребо-
ваться  послать  сигнал XOFF (ASCII 19), чтобы  остановить  поток
данных, если они поступают  слишком  быстро  и она не успевает их
обрабатывать.  Код XON (ASCII 17) сообщает удаленной станции, что
можно продолжить передачу.  Отметим,  что PCjr не может принимать
данные  во время дисковых операций; чтобы снять  это  ограничение
можно использовать XON и XOFF.
   В зависимости от  сложности  используемого  протокола  обмена,
принимаемые данные могут требовать простой или сложной обработки.
Может быть получен один из набора  управляющих кодов, приведенных
в [7.1.9]. Те из них, которые являются ограничителями данных чаще
обнаруживаются при синхронном обмене.  При выводе получаемых сим-
волов на экран учитывайте влияние символов перевода строки (ASCII
10), поскольку некоторые  языки  (включая  Бейсик)  автоматически
вставляют  перевод  строки после возврата каретки; в этом  случае
исключайте переводы строки из принимаемых  данных, чтобы избежать
пустых строк при выводе.  На рис.  7-2 показана  коммуникационная
процедура, включающая также код передачи, обсуждаемый в [7.1.6].

   Высокий уровень.


   Для коммуникационной процедуры, написанной на интерпретируемом
Бейсике,  время очень существенно.  Обработка  медленна,  поэтому
если процедура приема неверно  сконструирована,  то входной буфер
может  заполниться (т.е.  произойдет переполнение) в то время как
программа еще будет  анализировать  ранее полученные данные. Оче-
видным  решением  этой  проблемы является  максимально  возможный
размер буфера.  При загрузке Бейсика размер буфера ввода устанав-
ливается добавлением к команде ключа /C:.  BASICA /C:1024 создает
буфер размером в 1K и это  минимальное  число для скорости обмена
1200  бод (сложным процедурам может понадобиться 4096 байт).   По
умолчанию используется размер  буфера  равный  256 байтам и такой
буфер имеет то преимущество, что он может быть целиком помещен  в
одну символьную переменную.  Такой  размер буфера можно использо-
вать только при скорости обмена 300 бод и ниже.
   Бейсик  читает  из буфера с помощью  оператора  INPUT$  (можно

использовать также INPUT# и LINE  INPUT#, но INPUT$ более гибок).
Этот оператор имеет форму INPUT$(числобайт,номерфайла). Например,
INPUT$(10,#1) читает 10 байтов  из коммуникационного канала, отк-
рытого как файл #1.  Если размер буфера не превышает 256  байтов,
то очень удобно читать все  содержимое  буфера  за один раз.  LOC
сообщает  сколько байтов данных находится в буфере в  данный  мо-
мент. Поэтому напишите  оператор  INPUT$(LOC(1),#1)  и в S$ будут
записаны все данные с момента последнего доступа к буферу. Конеч-
но, если LOC(1) = 0, то  буфер  пуст  и  процедура должна ожидать
пока  данные будут получены.  Отметим, что EOF(1) также можно ис-
пользовать для  проверки  состояния  буфера,  так как эта функция
возвращает  -1  если буфер пуст и 0, если там есть хотя  бы  один
символ.
   После того как данные записаны в S$ программа должна проверить
не  содержатся ли там управляющие коды.  Функция INSTR  выполняет
эту задачу быстрее всего.   Напомним, что ее параметрами являются
сначала  позиция, с которой надо вести поиск в строке, затем  имя
строки и, наконец, символ  (или  строка)  который  ищется.  Чтобы
найти   символ   XOFF  (ASCII  19)  оператор  должен  иметь   вид
INSTR(1,S$,CHR$(19)). Чтобы найти второе появление нужного управ-
ляющего  символа  повторите поиск в  строке,  начиная с  символа,
следующего за позицией, в которой найден первый.
   Обычно процедура ввода  исключает большинство управляющих сим-
волов  из принимаемых данных, с тем чтобы они нормально выглядели
при выводе.  Затем данные выводятся на экран, пересылаются в дру-
гое  место в памяти, а иногда записываются на диск или  выводятся
на принтер. В процессе  всей  этой  деятельности программа должна
постоянно  возвращаться к просмотру не поступили ли новые данные.
Если оказалось, что буфер заполняется слишком быстро, то програм-
ма  может послать сигнал XOFF, останавливая поток данных.  Затем,
после того как полученные  данные  буду декодированы, можно снова
разрешить  передачу данных.  Конечно, необходимо  чтобы  протокол
обмена поддерживал XON и XOFF. Программы, написанные на интерпре-
тируемом Бейсике, обычно могут использовать XON/XOFF для установ-
ления соответствия скоростей  при  приеме данных, но при передаче
данных такая программа часто не может достаточно быстро  отреаги-
ровать на получение сигнала XOFF..
 .
500 '''здесь находится процедура передачи (см. [7.1.6])
 .
 .
600 IF LOC(1)>100 THEN XOFF = 1: PRINT #1,CHR$(19)
610 C$ = INPUT$(LOC(1),#1)   'читаем содержимое буфера
620 '''выделяем из данных управляющие символы
630 IF INSTR(1,C$,CHR$(19))>0 THEN 800  'получен XOFF
640 IF INSTR(1,C$,CHR$(17))>0 THEN 900  'получен XON
 .
 (здесь удаляются ненужные управляющие символы
 .
700 PRINT C$                 'выводим данные на экран
710 IF LOC(1) > 0 THEN 600   'если получены данные, то читаем их

720 IF XOFF = 1 THEN XOFF = 0: PRINT #1,CHR$(17)
 .
 .
800 'реакция на XOFF
 .
900 'реакция на XON

   Если функция LOF применяется к коммуникационному порту, то она
возвращает  количество свободного места, оставшееся в буфере вво-
да.  Например, если COM1 открыт как #1, то LOF(1) сообщит свобод-
ного  пространства.  Это может быть полезно для определения,  что
буфер почти полон.  Отметим,  однако, что оператор LOC возвращает
позицию указателя в буфере и это значение может быть использовано
для той же  цели.  Например,  если  COM1  открыт как #3, а размер
буфера  ввода  равен  256 байтам, то до тех пор, пока  LOC(3)  не
будет равен 256, буфер не полон.