Здравствуйте Eugene, вы писали:
E>Вызывает сомнение строка
E>cto.WriteTotalTimeoutMultiplier = 2*CBR_9600/dwBaudRate;
E>CBR_9600 определена как 9600, поэтому если скорость dwBaudRate больше,чем 19200, то WriteTotalTimeoutMultiplier = 0, а константа WriteTotalTimeoutConstant вообще не определена.
WriteTotalTimeoutConstant у меня равна нулю, просто в приведенном исходники отсутствовали строчки
COMMTIMEOUTS cto;
ZeroMemory(&cto, sizeof(COMMTIMEOUTS));
E>Хотя факт, что модем возвращает эхо, вроде говорит о том, что он данные получил. А в терминале-то модем откликается на ATZ\r?
В терминале модем нормально работает.
E>С параметрами DCB,контролем четности и т.д. все в порядке?
Параметры DCB ставятся без ошибок. Parity:NONE.
E>Для работы с COM-портами есть неплохой класс у PJ Naughter:
E>http://www.naughter.com/serialport.html
E>Из своего опыта: я использую WaitCommEvent для отслеживания изменения состояния CONNECT в отдельном потоке, запись/чтение делаю также в отдельном потоке, порт открываю в "Nonoverlapped" режиме,
E>регулируя временные характеристики протокола установкой констант COMMTIMEOUTS. Такой способ существенно (до банального) упрощает текст программы, реализующей собственно протокол, без какой-либо потери функциональности, ведь по сути приведенный однопоточный код все равно блокирует поток,
E>ожидая завершения каждой операции, но при этом код становится существенно сложнее. К примеру, задав нужные значения констант, достаточно сделать ReadFile и получить управление либо при успешном чтении, либо по истечении времени, определенного параметрами констант. Что касается записи, там это вообще некритично за счет многоуровневого буферирования (в том числе и в самом модеме). OVERLAPPED же режим был бы оправдан, если передающий или принимающий поток могли бы делать нечто полезное после начала операции и вплоть до ее завершения.
Я тоже использую два потока. Один управляет окном, другой работает с момдемом. OVERLAPPED использую для того, чтобы одновременно можно было ждать как минимум два события: завершения вывода и завершения программы. В синхронном режиме скорее всего придется делать TerminateThread при выходе из программы. Кроме того, я слышал, что Win2K не дает открыть порт синхронном режиме.