|
Программирование COM под Windows, не могу справится с переполнением приемного буфера |
|
|
|
Nov 20 2012, 11:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 526
Регистрация: 8-04-05
Пользователь №: 3 960

|
Цитата(paskal @ Nov 19 2012, 20:10)  что переменная в которой хранился дескриптор порта (полученный вызовом CreateFile) - затирается. Не затирается, а Вы его затираете некорректной работой с памятью, указателями итп. В С и даже в С++ система особенно не отслеживает выходы за границы массивов, выделенной области памяти для объектов, адресуемых указателями итп. Ищите у себя где Вы затираете переменную. Цитата(ARV @ Nov 20 2012, 15:19)  что не так в моем рассказе? Если устройство использует аппаратные сигналы DTR и/или RTS для разрешения работы, то при закрывании порта эти сигналы сбросятся и устройство ничего выдавать не будет. Так, кстати поступают телефонные модемы по умолчанию.
|
|
|
|
|
Nov 20 2012, 11:53
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Цитата(MrYuran @ Nov 20 2012, 12:39)  Открыли порт - на куче появился дескриптор. Задали буфер - он лег рядом. Пошли писать - вышли за пределы и затерли соседние данные. Никто за вас не обязан отслеживать границы массивов. Я в шоке.Где TC пишет о своём буфере??? Речь идёт о стандарном виндовском. Цитата(dac @ Nov 20 2012, 13:36)  ТС походу объявил в проге массив, и считывает в него то что приходит с порта. и не проверяет размер, соответсвенно если пришло больше чем размер массива - пишет дальше  Цитата(paskal @ Nov 19 2012, 19:10)  ... Но есть еще отдельный режим, когда устройство посылает поток байт, а компьютер ничего с ними не делает...
|
|
|
|
|
Nov 20 2012, 12:20
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(ARV @ Nov 20 2012, 15:19)  я конечно извиняюсь... но нафига вообще открывать порт, если из него не берутся данные? перешла программа в "автономный" режим - закрывать порт, и точка. все, что туда придет, будет сброшено аппаратно, ничего нигде затираться не будет. потребуется снова войти в режим "связи" - заново открывается порт, очищается его буфер (было сказано, как) и работа начинается снова...
что не так в моем рассказе? А вот что не так  . Бывают конструкции внешних устройств, которые питаются за счет сигнальных линий СОМ-порта (т.к., в отличие от USB, питание на этот разъем не подается). К такому решению располагает уменьшение энергопотребления большинства МК (им такой мощности для питания достаточно), но отвращает, что СОМ-порт постепенно выходит из моды, исчезая из стандартных устройств ПК. Часто потупают так - отказываются от хэндшейкинга, а освободившиеся линии DTR и RTS используют для питания. При этом напряжение на них уставливают в "противофазе", чтобы получить побольше разность потенциалов, и тогда из нее можно получить стабилизированное 5 вольт. Закрытие СОМ-порта приведет к тому, что выставленные уровни DTR и RTS изменятся, т.к. закрытый СОМ-порт не держит своих прежних установок. А питание внешнего устройства по многим причинам прекращать бывает нежелательно. Особенно в тех случаях, когда оно работает в ждущем режиме - не постоянно посылки гонит, а лишь в случае наступления того или иного события. Вот и было бы заманчиво установить такой режим (перепрограммирование СОМ-порта без его закрытия), чтобы (временно) отказаться от приема сообщений, но сам СОМ-порт не закрывать, чтобы сохранить уровни DTR и RTS. Всевозможные идеи (а таких можно выдвинуть много) о том, как можно организовать альтернативное питание, не взирая на полярность DTR и RTS, можете оставить при себе. Сейчас же интересует только одна вещь - возможно это сделать программным путем или невозможно. И выяснить этот вопрос хотелось бы раньше, чем брать в руки паяльник и курочить внешнее устройство.
|
|
|
|
|
Nov 20 2012, 12:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Xenia @ Nov 20 2012, 16:20)  А вот что не так  . Бывают конструкции ... Xenia, бывает, что и корова летает... при себе можно вообще оставить все попытки подсказать топикстартеру методы решения его проблемы, ограничившись просто советом найти и исправить ошибку в программе - ведь это очевидно все, не так ли? кстати, топикстартер и просил "временно приостановить прием" - что может быть лучшепроще закрытия порта для этого?!
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Nov 20 2012, 14:52
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(ARV @ Nov 20 2012, 16:32)  Xenia, бывает, что и корова летает... при себе можно вообще оставить все попытки подсказать топикстартеру методы решения его проблемы, ограничившись просто советом найти и исправить ошибку в программе - ведь это очевидно все, не так ли? кстати, топикстартер и просил "временно приостановить прием" - что может быть лучшепроще закрытия порта для этого?! Вы невнимательно читали его просьбу, а потому так неадекватно реагируете. Топикстартер САМ наотрез отказался закрывать СОМ-порт, вот так обосновав свой отказ: Цитата(paskal @ Nov 19 2012, 21:16)  Можно между посылками закрывать порт и открывать когда нужно послать очередной раз. Но это тоже много лишних действий - после очередного открытия надо настраивать таймауты, режимы через dcb. Вот если бы можно было переводить порт как бы в спячку, чтоб он временно ничего не принимал. Но как это сделать я не знаю. Т.е. изначально поставил задачу так, чтобы решение не содержало закрытия порта.
|
|
|
|
|
Nov 20 2012, 15:24
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769

|
Цитата(Сергей Борщ @ Nov 19 2012, 22:10)  Но подумайте, что вы такое пишете? Дескриптор в винде - это указатель, которая винда дает вам при открытии прота. Вы его храните у себя, как он может потеряться? Разве что ваша программа неловким движением что-то пишет в ту ячейку, куда вы положили этот указатель. Ваша правда, это я накосячил. Сегодня потрассировал внимательнее. Оказалось что я очищал буфер путем определения количества байт в нем ф-ей ClearCommError, потом читал всю эту длину одним махом в свой буфер. А когда мусора было слишком много, больше моего буфера, то соответственно терлись соседние данные. Вылечил заменой на PurgeComm. Всем спасибо, ваши советы подтолкнули где искать ошибку.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|