|
Программирование COM под Windows, не могу справится с переполнением приемного буфера |
|
|
|
Nov 19 2012, 16:42
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769

|
Цитата(Xenia @ Nov 19 2012, 19:17)  Посоветую увеличить размер буфера (можно входного и выходного сразу). Нет, не годится. Количество мусора, который может прийти неограничено. Буфер любого размера все равно когда то переполнится.
|
|
|
|
|
Nov 19 2012, 16:52
|

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

|
Цитата(paskal @ Nov 19 2012, 20:42)  Нет, не годится. Количество мусора, который может прийти неограничено. Буфер любого размера все равно когда то переполнится. Буфер (тот, который по SetupComm заводится) самоочищается на столько байт, сколько вы читаете из COM-порта. Ну, а если вы открыли COM-порт, как файл, и погнали в него с внешнего устройства информацию, а средства оперативного чтения (хотя бы раз в секунду) не предусмотрели, то вы сами себе злобный Буратино  . Обычно на таймер (ПК-шный) нагружают процедуру, которая периодически с каким-то постоянным периодом читает из СОМ-порта и хотя бы на диск эти данные пишет, если сама не знает, что с ними делать. Буфер не хранилка данных, а лишь средство, чтобы продержаться (не потерять данные) между их поступлением в ПК и чтением их из программы.
|
|
|
|
|
Nov 19 2012, 18:20
|

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

|
Цитата(paskal @ Nov 19 2012, 21:16)  Можно между посылками закрывать порт и открывать когда нужно послать очередной раз. Но это тоже много лишних действий - после очередного открытия надо настраивать таймауты, режимы через dcb. Вот если бы можно было переводить порт как бы в спячку, чтоб он временно ничего не принимал. Но как это сделать я не знаю. И еще я не понимаю почему простое переполнение приводит к таким последствиям что забиваются переменные. Может это тоже можно как то устранить? Мне не понятно ваше возражение о том, что "Буфер любого размера все равно когда-то переполнится". С чего бы ему вдруг переполняться, если вы посылки регулярно забираете? Этот буфер FIFO, и переполниться он может только если посылки будут приходить, а получать вы их не будете. Если вы наотрез отказываетесь использовать SetComm для установки размера буфера, то буфер все равно будет, только по умолчанию в 16 байт. Влезает в них ваша посылка? На ваш вопрос я уже ответила (или попыталась ответить) советом увеличить размер буфера. Если вы знаете размер посылки, то сделайте размер приемного буфера раз в 10 больше, чем этот размер. А еще лучше, поставьте 30000 и проверьте, пропал ваш синдром или нет. Цитата(zombi @ Nov 19 2012, 22:18)  Неужели Вы думаете что винда может не контролировать переполнение буфера и что то там затирать?  Винда не обязана заполнять всю свою память или писать на диск всю ту муру, что приходит на СОМ-порт. Она складирует "неполученные отправления" до тех пор, пока не кончится место в заказанном программой (которая тот СОМ-порт открыла) буфере. Эти данные уже не пропадут, но попадут те, которые пришли вслед за ними, и которым места в буфере нехватило.
|
|
|
|
|
Nov 19 2012, 18:50
|

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

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

|
Цитата(zombi @ Nov 19 2012, 21:18)  1. Попробуйте всегда перед началом работы с портом выполнить PurgeComm. Не получится. После переполения теряется дескриптор, а он нужен в том числе и для PurgeComm. Цитата(zombi @ Nov 19 2012, 21:18)  2. Не думаю что виндовский буфер может что то затирать кроме себя.  Неужели Вы думаете что винда может не контролировать переполнение буфера и что то там затирать?  Честно - совсем так не думал. Но это происходит и я не могу понять почему. Цитата(Xenia @ Nov 19 2012, 21:20)  Мне не понятно ваше возражение о том, что "Буфер любого размера все равно когда-то переполнится". С чего бы ему вдруг переполняться, если вы посылки регулярно забираете? Этот буфер FIFO, и переполниться он может только если посылки будут приходить, а получать вы их не будете. Забираю я из буфера не регулярно. А ненужные посылки идут непрерывно. Ситуация такая. Есть посылки которые шлет компьютер по нажатию мышкой, и получает тут же ответ. Это все работает. А можно переключить пульт в автономный режим. И в этом режиме в компьютер непрерывно шлется мусор. Компьютер в это время ничего не делает, но буфер его наполняется мусором. И количество мусора ничем не ограничено. Цитата(Xenia @ Nov 19 2012, 21:20)  На ваш вопрос я уже ответила (или попыталась ответить) советом увеличить размер буфера. Если вы знаете размер посылки, то сделайте размер приемного буфера раз в 10 больше, Да хоть в 1000 раз, все равно он теоретически может переполниться, я уже сказал что такой вариант мне не подходит.
|
|
|
|
|
Nov 19 2012, 19:39
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769

|
Цитата(Сергей Борщ @ Nov 19 2012, 22:10)  Но подумайте, что вы такое пишете? Дескриптор в винде - это указатель, которая винда дает вам при открытии прота. Вы его храните у себя, как он может потеряться? Разве что ваша программа неловким движением что-то пишет в ту ячейку, куда вы положили этот указатель. Ну не знаю, просто говорю что вижу в отладчике. А я этот дескриптор не трогаю. Да и происходит это во время когда моя программа ничего не делает, но в порт летит мусор. Завтра еще перепроверю. Ну а как бы временно приостановить прием есть варианты?
|
|
|
|
|
Nov 20 2012, 08:50
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(paskal @ Nov 19 2012, 23:39)  Ну а как бы временно приостановить прием есть варианты? Прием останавливается сам, как раз при переполнении буфера (при этом порт переходит в состояние ошибки). Затираться ничего нигде не должно. Цитата Ну не знаю, просто говорю что вижу в отладчике. А я этот дескриптор не трогаю. Да и происходит это во время когда моя программа ничего не делает, но в порт летит мусор. Ищите ошибку у себя в программе. Скорее всего вы не обрабатываете ошибки, которые функции работы с портом будут возвращать после переполнения буфера.
|
|
|
|
|
Nov 20 2012, 09:39
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(zombi @ Nov 19 2012, 22:18)  2. Не думаю что виндовский буфер может что то затирать кроме себя.  Неужели Вы думаете что винда может не контролировать переполнение буфера и что то там затирать?  Открыли порт - на куче появился дескриптор. Задали буфер - он лег рядом. Пошли писать - вышли за пределы и затерли соседние данные. Никто за вас не обязан отслеживать границы массивов. Цитата(Сергей Борщ @ Nov 19 2012, 23:10)  Дескриптор в винде - это указатель, которая винда дает вам при открытии прота. Вы его храните у себя, как он может потеряться? У себя - это где? А буфер где?
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|