История изменений
Исправление
gh0stwizard,
(текущая версия)
:
И еще, если вдруг решишь повторить телнет. Алгоритм парсера пишется на основе посимвольного разбора. Никаких регепсов и других извращений не пытайся вытворять, этим только усложнишь жизнь. В одном пакете тебе может придти пачка данных причем управляющие символы могут быть где угодно: вначале строки с текстом «255 251 3 Hello World!\r\n», в середине текста «Hello 255 253 3 World!\r\n», т.е в любом месте.
Поскольку управляющий поток весьма просто отделить от данных исходя из спецификации протокола, то я делал так. Читаем данные из сокета, проверям, что первый управляющий символ (255), далее разбираем каждый код команды до тех пор пока точно не определим команду (находим либо ASCII-символ, либо 255 240). Тем самым мы точно знаем, что далее идет текст, но это не все. Проверим всю строку еще раз на наличие кода 255. Если не встречается, то парсим строку (запускаем команды, пишем результат). Если встречаем, то запоминаем отрезок текста до управляющего символа и парсим управляющий поток. Потом повторяем действия с вырезкой (+склеивание с предыдущим куском текста) и выполняем команду.
Кажется, что сложно, но на деле все очень просто и логично. Окончанием строки текста в этом протоколе всегда является «\r\n». Однако, не стоит забывать про буферизацию со стороны ОС, иногда большие данные могут разбиться на несколько пакетов, скажем по 4096 байт (по столько же байт ты читаешь с помощью read) и в первом пакете может не обнаружиться «\r\n». Это редкость, но не стоит про такую вероятность забывать (в своей версии на это можешь забить).
Исходная версия
gh0stwizard,
:
И еще, если вдруг решишь повторить телнет. Алгоритм парсера пишется на основе посимвольного разбора. Никаких регепсов и других извращений не пытайся вытворять, этим только усложнишь жизнь. В одном пакете тебе может придти пачка данных причем управляющие символы могут быть где угодно: вначале строки с текстом «255 251 3 Hello World!\r\n», в середине текста «Hello 255 253 3 World!\r\n», т.е в любом месте.
Поскольку управляющий поток весьма просто отделить от данных исходя из спецификации протокола, то я делал так. Читаем данные из сокета, проверям, что первый управляющий символ (255), далее разбираем каждый код команды до тех пор пока точно не определим команду (находим либо ASCII-символ, либо 255 240). Тем самым мы точно знаем, что далее идет текст, но это не все. Проверим всю строку еще раз на наличие кода 255. Если не встречается, то парсим строку (запускаем команды, пишем результат). Если встречаем, то запоминаем отрезок текста до управляющего символа и парсим управляющий поток. Потом повторяем действия с вырезкой (+склеивание с предыдущим куском текста) и выполняем команду.
Кажется, что сложно, но на деле все очень просто и логично. Окончанием строки текста в этом протоколе всегда является «\r\n». Однако, не стоит забывать про буферизацию со стороны ОС, иногда большие данные могут разбиться на несколько пакетов, скажем по 4096 байт и в первом пакете может не обнаружиться «\r\n». Это редкость, но не стоит про такую вероятность забывать (в своей версии на это можешь забить).