Страница 12 из 27
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, буфер не полон.
|