Веб-сервер - как разбирать запросы?Асинхронный потоковый токенизатор? - PullRequest
5 голосов
/ 27 февраля 2011

Я пытаюсь создать простой веб-сервер на C # в стиле программирования асинхронных сокетов.Цель очень узкая - сервер Comet (http long-polling).

У меня запущена служба Windows, она принимает соединения, выдает информацию о запросе на консоль и возвращает клиенту простой фиксированный контент.

Теперь я не могу найти управляемую стратегию для асинхронного и безопасного анализа данных запроса.Я написал синхронные парсеры LL1 раньше.Я не уверен, подходит ли LL1 Parser для HTTP.Я не знаю, как токенизировать входной поток асинхронно.Все, о чем я могу думать, - это иметь входной буфер для каждого клиента, читать его, затем копировать его в StringBuilder и периодически проверять, есть ли у меня полный запрос.Но это кажется неэффективным и может привести к трудностям в отладке / сопровождении кода.

Кроме того, существуют две фазы подключения: получение запроса полностью и отправка ответа - в этом случае после некоторой задержки,Как только запрос будет подтвержден и выполним, только тогда я планирую зарегистрировать соединение в диспетчере длинных опросов.Однако неправильно работающий клиент может продолжать отправлять данные и заполнять буфер, поэтому я думаю, что мне нужно продолжать отслеживать и очищать входной поток во время фазы ответа, верно?

Любые рекомендации по этому поводу приветствуются.

Полагаю, первый шаг - узнать, возможно ли эффективно токенизировать сетевой поток асинхронно и без большого промежуточного буфера.Даже без надлежащего парсера те же проблемы создания токенизатора применимы к чтению «строк» ​​ввода за раз или даже чтению до двойных пустых строк (один большой токен).Я не хочу читать по одному байту за раз из сети, но я также не хочу читать слишком много байтов и хранить их в каком-то промежуточном буфере, верно?

1 Ответ

2 голосов
/ 27 февраля 2011

Для HTTP лучший способ - полностью прочитать заголовки в памяти (до тех пор, пока вы не получите \r\n\r\n), а затем просто разделить на \r\n, чтобы получить заголовки и каждый заголовок на : для разделения имени и значения.

Для этого не нужно использовать сложный парсер.

...