![]() |
|
|
![]()
|
|
| Гость_Бегемот |
|
|||
|
Unregistered |
Всем здравствуйте.
Необходимо читать и писать в COM-порт данные. Устройство - сотовый телефон, подключен через USB, но эмулируется com-порт. Данные нужно отправлять и принимать только с телефона. Порт работает в синхронном режиме и есть несколько вопросов: 1. Хочу прочитать данные с телефона, пишу в порт команду WriteFile("ATxxx"...) - команда записалась. Теперь надо прочитать данные - ReadFile(...). Какой указывать буфер? Сколько байт читать, если заранее ответ не известен? Можно указать заранее буфер размером в мегабайт, потом посмотреть сколько байт было реально прочитано и уже из буфера получить это количество байт - правильно ли это? И как вообще получать данные из порта после записи в него AT-команды? 2. После WriteFile сразу необходимо сделать ReadFile, о таймаутах будет заботится драйвер порта? Я имею в виду - структуру COMMTIMEOUTS я заполню, все остальное - уже не моя забота? Заранее спасибо за ответы! |
|||
|
||||
| Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Я еще на всякий случай сразу после WriteFile делаю PurgeComm.
Сколько прочитно байт, ты посмотришь в переменной LPDWORD lpNumberOfBytesRead, адрес которой тыпередаешь в функцию ReadFile. НО!!! Я бы не использовал такой подход по той причине, что ВСЕГДА у тебя функция будет завершаться по таймауту, так как ты хочешь запрашивать заведомо больший буфер, чем будет реально считан, поэтому при каждом вызове этой фунции ты будешь дожидаться таймаута, а это сильно придаст тормозов твоей программе. Я бы поместил функцию чтения в отдельный поток, в котором все время считывал бы по несколько символов (например, по 128, зависит от скорости порта, если болшая и стабильная, то можно и поболее) с небольшим таймаутом, и считанные символы помещал бы в специальный буфер-очередь, который сдвигал бы по мере забора из него символов уже твоим рабочим потоком. Естественно, не забыв про синхронизацию. Тогда ожидание по таймауту будет происходить в отдельном потоке, не затормаживая твой основной поток при каждом вхождении в функцию ReadFile. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
1), 2) Пиши и читай в (из) порт хоть по байту, работай как с файлом. После того, как откроешь девайс (он Exclusive) никто другой (процесс) не сможет его открыть. Смотри еще иногда что возвращает GetLastError.
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Гость_Бегемот |
|
|||
|
Unregistered |
1. Понял. Т.е. читать или побайтово или небольшими партиями в заведомо большой буфер. Так?
2. Все же тайм-ауты. После WriteFile сразу делаю ReadFile (Purge чтобы очистить буфферы порта), о задержках будет заботиться драйвер? И тогда уж еще вопрос |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
1) Да, если читаешь по 1 байту, то и буфер бери 1 байт или 2=1+1(для '\0')
2) Да. 3) Хз. Пути господни неисповедимы ;) -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Парсить надо обязательно. Дело в том,что никто не защищен от возникновения на линии "левых" символов, а также паразитных "эхо-символов", и хоть в случае с телефоном это может и маловероятно, но ты получишь хороший опыт реализации помехоустойчивого протокола. А если ты еще потом будешь эти функции на RS-485 использовать, то там "лишние" символы фильтровать надо обязательно!
Да. Точнее,не знаю, то именно - драйвер, или ядро Виндоус, или какие-то dll но не ты =) Совет: если есть сомнения в работе с портами - не полинись купить/сделать перекрестный шнурок, и законнектить по нему два компа. Тогда на одном из них хапускаешь терминалку, на другом - свою прогамму, и имеешьудовольствие ;) Потому что твой телефон - устройство "слепое", и может быть так, что ты все напишешь правильно, но будет дело в каких-нибудь мелочах. А купив шнурок, ты всегда сможешь смоделирвать ту или иную ситуацию, и отладить программу по шагам. Да, кстати, предупрежу заранее про отладку. В режиме пошаговой отладке функция ReadFile не работает! (точнее, может не работать.). Поэтому ели ты хочешь анализировать ее результат, тебе надо брекпоинт ставить на следующую за ней команду, чтобы функция отработала именно в режиме "выполнения программы",а не пошаговой отладке. Я на этом один раз очень много ценного времени потерял... -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| JoyEx |
|
||||||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Ты немного не так спросил или я не так понял. Если ты имел в виду события посл. порта, то тогда ты сам должен "заботиться" и вот тебе простой пример чтения данных из порта (hComm).
ПисАть в порт можно WriteFile и синхронно, без OVERLAPPED. А то у тебя, Гость_Бегемот, получается как в жизни
Мораль: не спрашивай как делать, делай и всё тут! Сначало бери -------------------- Если ты уже никого не боишься, значит ты самый страшный |
||||||
|
|||||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Я для себя пишу А код, который ты привел - это разве не асинхронный режим? У меня случай простой: послал команду - получил данные. Следующая команда - следующие данные, т.к. я буду не только в телефон передавать, но и получать данные вперемежку.
Спасибо! Попробую сначала получить результат (вернее, уже все заработало), а потом уже буду пробовать парсить. Дело в том, что в данных тоже могут встречаться символы \r\n. Ну, это уже буду смотреть конкретно применительно к AT-командам своего телефона, там как-то хитро сделано получение SMS сообщений из него. Еще раз всем большое спасибо! Поднял бы вам рейтинги, но не дают, говорят, 100 сообщений надо |
||||
|
|||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
JoyEx
парочка замечаний и вопрос. во первых, не понятна конструкция (WaitForMultipleObjects(2, Handles, FALSE, INFINITE), если INFINITE, то значит не выйдем по таймауту=> зачем асинхронная передача. Во-вторых, у меня при чтении по событию EV_RXCHAR зачастую очередь была нулевая! То есть событие взвелось(EV_RXCHAR), а очередь не обновилась. Порыскал по паутинке, оказалось, что это не только у меня и что толком проблему не решили(был только способ с синхронных чтением). Вот по этой проблеме нет ли соображений? Добавлено @ 08:10 Бугемот
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| JoyEx |
|
||||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Да, асинхронный. Не забудь про SetCommMask
1) Если что, то выйдем из WaitForMultipleObjects по Handles[1], т.е. по g_hEventQuit 2) Хз. Может быть буфер у тебя был большой и ты выходил из ф-ции через час (по таймауту)?! -------------------- Если ты уже никого не боишься, значит ты самый страшный |
||||
|
|||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
JoyEx
Нет. Просто когда данные приходили, я считывал из очереди количество символов, которое там находилось. И снова ждал, когда придет символ. И вот когда он приходит, длина очереди равна нулю. Добавлено @ 11:31 http://forum.vingrad.ru/index.php?showtopi...=clearcommerror -------------------- я не гольфист - я хоккеист |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Ответил тебе в твоей теме. Ты не проверяешь *lpEvtMask на EV_RXCHAR.
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Именно, но в добавок к этому нужно внимательно прочитать, в каком формате передаются данные, и собственно, что передается. Если ты будешь знать количество байт, которое будет передано между этими символами, то проблема отпадет сама собой, а эти символы ты сможешь ловить в качестве подтверждения правильности получения пакета. Опять же, если у тебя информация в пакетах представлена в виде ASCII-символов (а такое очень часто делают), то у тебя действительно не встретятся эти символы в данных и все будет нормально. Так что мой тебе совет, еще раз тебе говорю - отдельно разберись и с мануалом к телефону, чтобы четко понимать его протокол, и отдельно с ком-портом, чтобы при разборе протокола уже четко быть веренным, что сам ком-порт ты обслуживаешь правильно. Не торопись решать сразу все задачи, решай их по отдельности, и все получится. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Dreamer_0x01 А вдруг у него HDLC?
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Хм, тогда я не понимаю, откуда брать настройки (четность, биты и т.д.) - из мануала к модему? Сдается мне - все же для COM-порта. Откуда брать эти настройки? С учетом того, что ком-порт у меня эмулируется, т.к. физическое подключение телефона через usb. |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Бугемот
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Это ноутбук?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Нет, обычный компьютер. Сотовый телефон подключен через USB-порт. COM-порт виртульаный. Формат вывода я определил терминальной программой - шлю AT-команду и смотрю ответ |
|||
|
||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Поздравляю всех с Новым Годом!
Год прошел, но вопросы остались
Т.е. все же читать кусками, но выставить небольшой таймаут. Т.к. если, например, взял я буфер 128 байт, а пришло данных меньше - все равно функция чтения завершится по таймауту?
Где можно взять настройки для COM-порта? Он у меня виртуальный Ну и остался вопрос по таймаутам - где их взять? Нашел доку к модему на AT-команды, про таймауты там ни слова |
||||
|
|||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Вот открываю порт:
Вот пытаюсь прочитать данные:
В результате программа виснет, т.е. по таймауту чтение не завершается Если прочитать 5-10 байт, то читается последняя записанная в порт команда, хотя ATE0, ATQ1 - выполнил. В терминальной программе все нормально работает, у меня - нет. Подскажите, пожалуйста, что не так? |
||||
|
|||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Попробуй
ReadIntervalTimeout = MAXDWORD ReadTotalTimeoutConstant = 0 ReadTotalTimeoutMultiplier = 0 -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Посмотрел в отладчике - значения 0. Поставил вручную - ничего не изменилось Как-то странно и непонятно все работает В принципе, рассчитал значения: На чтение 80 байт (хочу в такой буфер читать) при скорости 57600 б/с надо ~14мс. Межсимвольный интервал 0.0875мс Пробовал выставить вручную - тот же эффет, программа виснет надолго |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Если читать заведомо меньшее количество байт (меньше чем придет), то все читается. Если выставить буфер больше - виснет
Вроде и таймауты выставлены Добавлено @ 13:16 Если читать заведомо меньшее количество байт (меньше чем придет), то все читается. Если выставить буфер больше - виснет О! Виснет не намертво, но таймаут - минуты три |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Тогда ReadIntervalTimeout ~= 0
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Да, сделал:
и вроде нормально работает. Большое спасибо! Добавлено @ 15:12 Вот только иногда после открытия посылаю команду, а выбираю оттуда всякий мусор, хотя вроде PurgeComm(m_handlePort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT|PURGE_RXABORT); Делаю. |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
А что PurgeComm() возвращает? Если FALSE, то тогда поможет GetLastError.
-------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
GetLastError рекомендуется делать после любой операции с портом?
|
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Так, с таймаутами разобрался.
Стандартный для большинства модемов AT-команды нормально проходят. Ответ получаю. Но как только посылаю команду для своего модема (например, получить производителя), в ответ - пусто |
|||
|
||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
У тебя OEM? Новый Год к нам мчится, скоро всё случится, сбудется, что снится, что опять нас обманут - ничего не дадут... - это про твой модем C Новым 2006 Годом! -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Dreamer_0x01 |
|
||||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
JoyEx
Да вы я тоже вижу фанатеете от текстов, произносимых Жуковым ;) "Ты едешь туда, где закат такой малиновый, ты видел его дома лишь наполовину..."
Именно. Причем, как я уже говорил, лучше выставлять не междусимвольный таймаут, а общий. Прочем, вижу, ты уже и сам это понял.
Нет. Как правило, операции типа ReadFile, SetCommTimeOut. PurgeComm имеют какой-то возвращаемый результат, это либо BOOL, либо UINT,либо int, либо DWORD, ну либо там еще что-то. Так вот во всех инх в случае успеха возвращаются отличные от нуля значения, в случае неуспеха - 0. То есть все подобные операции желательно заключать в следующие конструкции:
В таком коде ты увидишь сообщение о возникающих ошибках, и программа будет работать правильно, не подвешивая систему и не предлагая отправить отчет в майкрософт ;) Это сообщение отредактировал(а) Dreamer_0x01 - 2.1.2006, 23:40 -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||||
|
|||||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Да. Олег Жуков классный был человек. Бугемот, а куда Вы пропали? У Вас всё получилось? -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Всем здравствуйте.
Частично - с общим таймаутом на чтение работает с такими интерваллами: ct.ReadTotalTimeoutMultiplier = 2; ct.ReadTotalTimeoutConstant = 1; Это, если честно, многовато. Но при меньших значениях данные не читаются. Придется подбирать все же таймауты, в документации я не нашел этого значения. Ну а в остальном - все работает Вам очень большое спасибо за советы !!! Это сообщение отредактировал(а) Бугемот - 5.1.2006, 03:14 |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Всем снова здравствуйте.
Программе мне была нужна для отправки SMS сообщений, по работе приходится много отсылать, вот и хочу сделать для себя небольшой терминал. Вот так отправляю: Вот PDU: 07919732929090F0110B0B919732426654F70000A703D36110, программа pduspy раскодирует корректно. пишу отправку: AT+CMGS=24 (пробовал и макс. длину 140 - ничего) 07919732929090F0110B0B919732426654F70000A703D361101A (1A - это Ctrl+Z) И ничего ( Что неправильно? и как по-другому можно сформировать Ctrl-z? Попробовал просто сохранить сообщение в памяти, тоже не получается. Похоже, Ctrl-Z я неправильно посылаю. Читаю сообщения и любую доступную служебную информацию с телефона через АТ-команды - без проблем |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Я бы посоветовал создать отдельный топик на эту тему. И раздел вроде про мобильные устройства тоже где-то видел, может, там помогут...
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 2 Всего: 47 |
||||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
А какие таймауты для записи примерно будут для порта со скоростью 57600Кб. На конце порта - сотовый телефон.
я выставил вот такие
но результат все равно никакой |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Все, со всем разобрался. SMS не мог отправить потому что у моего телефона какой-то нестандартный режим отсылки сообщений
Остался один вопрос: я отсылаю команду и мне надо дождаться отклика, как его ждать? Я сейчас поставил sleep, т.е. просто тупо жду какое-то время, т.к. после отправки в порт команды отклик приходит с задержкой. А как правильно будет его получать, как отслеживать эту задержку? Ждать какое-то время до получения этого символа, но не больше определенного промежутка? |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Таймауты на то и созданы, чтобы грамотно ждать отклика. Но если уж не хочется переделывать - лучше не Sleep использовать, так ты поток усыпляешь намертво, а это не есть хорошо, лучше в цикле делай ReadFile, пока не прочитает то, что тебе нужно, либо пока не кончется установленное тобой количество попыток чтения. (оно соответственно будет равно твоему нужному времени, деленному на твой таймаут, установленный для чтения. )
Но вообще...Не понимаю, чем же тебе не понравились установки вида
И усе, никаких проблем! Устанавливаешь вместо ТВОЙ_TIMEOUT твое время, в течение которого нужно ждать приема, и все! Функция ReadFile будет ждать приема указанного тобой количества символов в течение времени ТВОЙ_TIMEOUT (в миллисекундах). Очень удобно! -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
ctm.ReadTotalTimeoutConstant=ТВОЙ_TIMEOUT; - влияет на все операции чтения.
А отклик мне надо ждать только на команду перед записью, поэтому тормозить все чтение общим тайм-аутом не очень хочется. У меня сейчас стоит межсимвольный - 2мс, но 5Кб считываются не 10 секунд, а меньше. Если выставить межсимвольный в 0, а Constant'ный - например в 100, то чтение визуально выполняется быстрее. Поэтому я им не воспользовался константным. Sleep мне тоже не нравится О, проверил сейчас константный - работает! Осталось один нюанс уточнить - сколько же ждать Большое спасибо! Добавлено @ 18:36 Причем если выставить константу заведомо больше, чем надо. То и ожидание будет длиться все это время, хотя данные уже точно пришли в порт Добавлено @ 18:37 Вобщем, или это не так уж удобно, или я чего-то не понимаю |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Проверил только что: если перед моей командой на запись (сначала команда, жду отклик, запись) отправить какую-нибудь другую - все, отклика с таймаутом в 100мс я дождусь. Если же сразу после открытия отправить эту команду - не дожидаюсь, т.е. отклик не приходит, ну и как тут быть
|
|||
|
||||
| Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
А менять таймауты в процессе работы не пробовал?
1. А откуда ты знаешь, что данные пришли? 2. Поверь, у меня это все работает, ведь это моя работа, и с ожиданием все в порядке, как только в приемном буфере порта накопится нужное количество символов, ожидание прекращается. 3. Ты случаем не в дебаггере это смотришь? ;) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Если честно - нет, такое практикуется вообще? У меня раз в 15 секунд из порта принимаются данные. Теперь проблема - в записи.
нет Т.е. рекомендуете для команд записи выставлять таймаут на чтение - больше чем на обычное чтение? Т.е. отправляется запрос на передачу данных (вот тут я и жду отклика), и в данном случае - изменить время ожидания? |
||||
|
|||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Всем еще раз здравствуйте. Никак не могу получить нормально отклик. ВОт код:
Вот, собственно, и все. Отклика я не дождался Чего-то я не понимаю |
|||
|
||||
| Dreamer_0x01 |
|
||||||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Зачем вообще выставлять таймаут на запись? Я все таймауты, начинающиеся со слова Write, присвоил нулю, и все прекрасно работает.
Может быть, ты хотел сделать так:
? Я бы посоветовал не использовать подобные конструкции. Даже если все работает - во время работы выдергиваешь кабель, получаешь жуткие тормоза, и предложение отправить отчет в микрософт. обязательно в таих конструкциях используй счетчик попыток. То есть, например, так:
Вот так ты свою программу не завесишь. Впрочем, это так, лирическое отступление, поделился печальным опытом, так сказать ;) А еще...Ты параметр dwnumber_read_bytes в функцию CSMSCOMPort::Instance()->ReadPort как передаешь? В фунции что у тебя принимается - сам параметр, или указатель, или ссылка, с этим усе в порядке? ;) Это сообщение отредактировал(а) Dreamer_0x01 - 13.1.2006, 16:45 -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||||||
|
|||||||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
"Количество попыток" - а зачем же тогда таймаут на чтение ??? Разве смысл не один и тот же - в течение какого-то времени опрашивать порт?
Проблема в том, что я не могу получить отклик, хотя таймаут на чтение выставлен заведомо бОльший. Зато через некоторое время, после отпарвки какой-нибудь "левой" команды - получаю отклик |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Почему - так? я перед циклом выставляю dwnumber_read_bytes = 1 и соответственно - жду первого пришедшего символа. Хотя, я тогда вообще перестал что-то понимать: как считать данные из порта, в цикле? Данные я запрашиваю порциям - в разных случаях по-разному. От 20 до 200 байт, в зависимости от того, что должен получить. И таймауты теперь уже меняю в процессе работы Для чтения большого объема выделяю общий буфер в 8Кб и заполняю его порциями по примерно 200 байт, чтение - в цикле. Dreamer_0x01, если Вас не затруднит, напишите, пожалуйста, как правильно получить данные из порта после отсылки команды? С учетом того что может прийти большой объем и чтение - порциям в цикле while? Заранее большое спасибо! Это сообщение отредактировал(а) Бугемот - 13.1.2006, 21:32 |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Еще раз. Если ты устанавливаешь таймаут заведомо больший, чем время, необходимое тебе для того, чтобы дождаться отклика, то и цикл тебе здесь никакой не нужен.
Если же таймаут все-таки меньший, то вот тогда как раз и нужен цикл, причем со счетчиком попыток чтения. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Соответственно, операция чтения повесит поток на время таймаута?
ну это равносильно тому, что выставить таймаут. Причем мне кажется - с таймаутом надежнее. Цикл я использую для того, чтобы получить большой объем данных маленькими порциями |
||||
|
|||||
| Dreamer_0x01 |
|
||||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
В общем, да. Именно поэтому я и предлагала анализировать количество попыток, а не делать одним единым большим таймаутом.
Я понимаю. надежность...не факт. Мне вот как раз кажется, что чем чаще контролиреушь ситуацию, тем лучше. Не затруднит, но пожалуйста, четко ответь на вопрос - ты знаешь, сколько символов должно прийти после запроса, или нет? От этого и будет зависеть алгоритм. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
||||
|
|||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Нет, не знаю. Есть два варианта: 1. Когда запрашиваю смс-сообщения из телефона. Здесь теоретически до 20-25Кб данных может прийти 2. Когда посылаю сообщение - надо дождаться отклика. Максимум 50-70 символов. НО точно - не знаю |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
хорошо, тогда вопрос такой - как ты определяешь конец ответа твоего телефона?
-------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Бугемот |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Есть два варианта:
1. я знаю, что объем ожидаемых данных не превышает, например, 100 байт. ТОгда делаю так:
соответственно я жду 100 байт в течение 5 секунд. Кстати, попутно вопрос: если данные придут раньше - чтение завершится, или все же будет ждать 100 байт и завершится по таймауту? 2. Заранее не знаю, сколько придет данных, может и 100 байт, а может и больше. Тогда читаю блоками по 200 байт (максимальная длина одного сообщения + служебная информация)
ну и читаю данные до тех пор, пока они читаются. Вот так делаю |
||||
|
|||||
| JoyEx |
|
|||
|
Дядя ![]() ![]() Профиль Группа: Участник Сообщений: 323 Регистрация: 21.6.2005 Где: Москва, РФ Репутация: 5 Всего: 12 |
Бугемот
У тебя только один выход из сложившейся ситуации - WaitCommEvent, и будешь знать что-как с уст-вом -------------------- Если ты уже никого не боишься, значит ты самый страшный |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
это уже асинхронный режим. Мне он не подойдет: я отправляю sms-сообщение через телефон, т.е. реально оно в телефоне не сохраняется. Когда приходит ответ - в нем информация только о том, что сообщение отправлено. Ну и как теперь угадать - какое-же из двух моих отправленных сообщений - действительно отправлено? Вот и приходится ждать отлик сразу же после отправки! |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
WaitCommEvent можно и для ожидания отклика тоже использовать.
Ладно, погоди, щас до работы доеду, и оттуда напишу свой вариант. -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
| Бугемот |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 27.12.2005 Репутация: 1 Всего: 1 |
Посмотрел еще раз ветку. Действительно, воспользуюсь вариантомDreamer_0x01, т.е. буду опрашиват порт 7 раз с таймаутом в секунду (например), ну или с таймаутом в полсекунды. И вынесу запись в отдельный поток. Получится отправка в среднем 10-15 сообщений в минуту, вроде пока должно хватить, хотя на пике явно будет нагрузка больше. Ну, это уже с заделом на будущее
Мне смысла нет использовать WaitCommEvent, т.к. пока не придет отклик, следующее сообщение посылать нет смысла. Я просто отклики друг от друга не отличу и не буду знать, какое же из двух сообщений действительно отправилось. |
|||
|
||||
| Dreamer_0x01 |
|
|||
![]() Терминатор ![]() ![]() Профиль Группа: Участник Сообщений: 780 Регистрация: 14.4.2005 Где: Санкт-Петербург Репутация: 9 Всего: 12 |
Так блин, тебе никто не предлагает послать кучу запросов и ждать кучу откликов. Естественно, все делается последовательно.
Погоди до завтра, полный цейт-нод, ночую на работе - утром показ прибора руководству ;) -------------------- Нет ничего невозможного. Есть цели, и есть время и силы на их достижение. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |