Re[7]: Что определяет ReadTimeout SerialPort?
От: curvex Россия  
Дата: 03.01.07 09:21
Оценка: 2 (1)
Здравствуйте, Andrej-V, Вы писали:


AV>>>А как в NET SerialPort определяет сколько байт прочитать: один, два, десять?

C>>Думаю, что никак.

AV>Я предполагал, что как-то используется какое-то время считывания или считывается определенное кол-во байт. Но или алгоритм более сложный (непонятно зачем) или определяется во время считывания какая-то другая величина (например, заканчивается время обработки сообщения — заканчивается считывание). Но не квантовая же механика пролезла в алгоритмы.

AV>Хотя судя по вашему ответу — это вопрос не практического сорта.

SerialPort ждет _любое_ отличное от нуля количество байт в течении времени заданного ReadTimeout. Если хотя бы один байт пришел, его и вернет. Если не пришло ни одного байта — кинет TimeoutException.


AV>Мне непонятны элементапрные вещи.

AV>Я посылаю команду, к примеру CONNECT.
AV>Сколько времени надо читать ответ? И когда ответ придет не может ли он окакзаться, к примеру CONN ( а вот ECT 9600 — просто не дочитаться и while в вашем коде закончиться).

А зачем вам что-то ждать? Рассмотрим такой сценарий: вы отправили ATDP1234567 и хотите получить CONNECT. До момента отправки ATDP убедитесь что буфер драйвера и буфер SerialPort не содержит никаких данных. То есть прочитайте все оттуда (например, конец предыдущего ответа модема, который был не полностью принят из-за таймаута) и выкиньте: дальше модем сам по себе данных в командном режиме посылать не будет. Отправьте ATDP. Читайте данные из порта в цикле пока не считаете CONNECT. Если прошло некоторое время, а CONNECT не появился, прекращайте читать данные.
Пусть даже остаток CONNECT придет позже — он будет считаться мусором и будет вычитан и отброшен перед посылкой следующей команды модему.

AV>Тогда может случиться так, что количество byteToRead == 0 — истина, только потому что, не хватило времени (времени выполнения цикла) для заполнения буфера, в которм хранятся считываемые байты (а введем Thread.Sleep(кол-во) в цикл — этот цикл бкдет работать большее количество раз). — Никак без времени считывания не обойтись (т.е. какое кол-во устанавливать в Sleep()?).


Тут надо четко определить семантику события "нехватило времени". Как правило это означает: жизнь не удалась — сообщение не пришло; начнем все сначала, отбрасывая все остатки жизни старой.

AV>>>Драйвер модема не гружу (работаю с модемом напрямую через порт). Thread.Sleep(500); — закомментировал. Время получения ответа — 0;


Разрешение таймера, используемого вами для измерения интервала между запросом или ответом — 20ms. Время передачи одного байт на скорости 9600 — около 1ms. Модем вполне мог успеть проинициализироваться и послать ответ за 20ms.

AV>А лампочки на модеме моргают на ATZ не 0mc.


Вообще, есть такая программка: PortMon.
Показывает байтики передаваемые и принимаемые последовательным портом (точнее его драйвером), команды отправляемые ему приложением и проч. В том числе показывает время этих событий, и, насколько я помню, использует таймер с более высоким разрешением для замера интервалов. Попробуйте ее.
Я все это — к тому, что лампочки — критерий не очень надежный. Самое правильное было бы посмотреть осциллогафом на линиях последовательного порта, но неуверен, что это доступно в Вашем случае.

AV>Вообще-то мне надо обмениваться 64-битными пакетами: послать 64-бита, принять ответ — 64 бита. Не знаю может ли быть разрыв в чтении (сосчитал 3 байта, потом пауза, потом остальные 5 байтов).


Вот для этого, как я уже писал, лучше определять конец пакета не по времени, а по специальному символу — концу или началу пакета. Пока его нет читаете или отбрасываете все как мусор. Пришел — читаете пакет.

Успехов,
Леонид.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.