Здравствуйте,
обыскался в поисках решения проблемы — и по чатам побродил, и поисковики помучал, и коллег помучал. Но... пока нет ответа. Хотя по-моему решение проблемы есть. И, что интересно, в unix проблема не возникает.
КОНФИГУРАЦИЯ:
win2k, telnet применяется к 127.0.0.1, запущен telnet-server.
в telnet (или в HyperTerm) эмулируется vt100.
через telnet вызывается моя прога.
ПРОБЛЕМА:
Программа посылает на терминал совокупность esc-последовательностей (позиционирование курсора) и символов.
В некоторый момент, после того как послано на терминал строго определённое кол-во символов,
текст начинает выводиться в произвольных местах экрана, хотя до этого всё работало нормально.
ПРЕДПОЛОЖЕНИЯ:
Сначала думал, что printf какой-то очень интеллектуальный при работе с vt-100... Когда число символов (вместе с неотображаемыми в сумме) достигает 80, происходит посылка \n.
Потом посмотрел capture в hyper term и обнаружил, что некоторые esc-последовательности меняются местами в перехваченных пакетах, или вообще затирают друг-друга. Хотя при запуске программы без всякого telnet, можно обнаружить, что на консоль все esc-последовательности выводятся в нужном порядке (правда в ms-dos нет никакого vt-100, и на экране конечно маразм).
То есть, видимо, есть некий буфер в vt-100, который переполняется, и начинается некорректное поведение терминала. Причём сразу все символы, выводимые программой, посылаются в одном пакете (похоже на то), и естественно происходит переполнение.
Короче говоря, то ли дело в line feed, но я перепробовал все мне известные настройки (включая посылку соотв. esc-последов.),
то ли проблема с БУФЕРОМ vt-100 с одной стороны и пакетом tcp/ip для telnet с другой.
Но КАК её решить, и что именно решать?!
ИНТЕРЕСНО:
что под unix таких проблем не возникает — но ведь там я тестирую непосредственно, без telnet, просто устанавливаю export TERM=vt100
Надо убедиться, что все выводы на экран делаются через одну систему. Например, только через write() или через fwrite() и т.п. и что весь вывод идёт в один поток — только в stdout или stderr.
Ещё в виндах есть фича — автоматическое дополнение \r к \n в "текстовых" потоках данных. А у VT100 есть настройка, которая делает тоже самое. Следовательно, к каждому выведеному '\n' у тебя может добавляться один лишний '\r'.
Правильный способ избежать этого — открыть stdout в режиме binary.
А переполнение "буфера VT100" — это из области фантастики
Здравствуйте, PK Sly, Вы писали:
PS>Очень похоже на проблему с буферизацией.
PS>Надо убедиться, что все выводы на экран делаются через одну систему. Например, только через write() или через fwrite() и т.п. и что весь вывод идёт в один поток — только в stdout или stderr.
Вывод я осуществляю по-тупому, через printf. Да и вообще ничего из передаваемых данных у меня не теряется. Проблема в том, что кое-что "чужое" к ним добавляется.
PS>Ещё в виндах есть фича — автоматическое дополнение \r к \n в "текстовых" потоках данных. А у VT100 есть настройка, которая делает тоже самое. Следовательно, к каждому выведеному '\n' у тебя может добавляться один лишний '\r'. PS>Правильный способ избежать этого — открыть stdout в режиме binary.
Это можно отключить в настройках HyperTerm, что я уже давно сделал.
PS>А переполнение "буфера VT100" — это из области фантастики
ВОТ!!! А почему???. Разве нет у терминала буфера. Ведь VT100 не рассчитан по-моему на то, чтобы кто-то бац и сразу 2000 символов на него выкинул!!!
Проблемы возникали похоже из-за того, что все данные посылались printf-ом в одну строчку. На каком-то уровне происходило переполнение какого-то буфера (знать бы какого!!!) и начинались глюки.
Решение оказалось следующим — если часто вызывать printf("\n\r"), то глюки не возникают. Конечно это не очень удобно, но зато работает, в отличие, скажем, от вызова fflush.
Проблема с выводом как бы решилась, ЗАТО возникла НОВАЯ ПРОБЛЕМА с вводом. Причём природа этих двух проблем видимо схожая....
лишние esc-последовательности на уровне клиента всё-таки вставляются — в конец и в начало посылаемых данных.
И в результате, если я хочу считать (scanf-ом или getch) с клавиатуры символ, то курсор передвигается в некую фиксированную от раза к разу позицию — где-то в середине экрана.
Никакие esc-последовательности позиционирования курсора не влияют на положение этой позиции.
Ещё могу отметиь, что использование различных telnet клиентов под windows/unix мне не помогло (и с вводом и с выводом)...
p.s. Решение "\n\r" не мог так долго найти, потому что пробовал по отдельности \r и \n, вместе почему-то не пришло в голову попробовать ...