Является ли длина содержимого единственным способом узнать, когда сообщение HTTP полностью получено? - PullRequest
0 голосов
/ 03 августа 2011

Я обычно рассматривал возможность написания протокола для своих собственных целей через TCP и столкнулся с проблемой определения конца сообщения.

Получив из HTTP, я увидел, что длина сообщения упоминается в Contentдлина и может быть методом определения того, что сообщение было полностью получено.Это единственный способ сделать это?Что произойдет, если этот заголовок отсутствует, поскольку AFAIK заголовки являются необязательными в HTTP-сообщении.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 03 августа 2011

Это единственный способ сделать это?

Есть и другие способы, например,

  • Имейте специальный разделитель, отмечающий конец (и, возможно, начало следующего сообщения). например Вы можете завершить все сообщения новой строкой, поэтому, чтобы прочитать сообщение, вы читаете все до новой строки. В этом случае вам необходимо убедиться, что содержимое сообщения не содержит саму новую строку, например, экранирование новых строк в сообщении при отправке и не экранирование при прочтении. Или закодируйте сообщения с помощью кодировки, которая не содержит символов новой строки (например, base64 или ascii-hex)

  • Отформатируйте сообщения так, чтобы они содержали структуру, позволяющую синтаксическому анализатору неявно определять начало и конец сообщения. например если вы отправляете json, вам придется анализировать json при получении данных, и как только все символы { и [ будут сопоставлены, вы получите полное сообщение.

  • префикс каждого сообщения с длиной. Это очень похоже на «Content-Length» в HTTP, но вместо этого вы кодируете длину в двоичном формате, например первые 4 байта каждого сообщения содержат длину следующих данных.

Что произойдет, если этот заголовок отсутствует, поскольку AFAIK заголовки являются необязательными в HTTP-сообщении.

Это более сложно, так как есть много дел, связанных с этим.

например. для HTTP / 1.0 в запросе должна быть длина содержимого, если на самом деле есть тело. Для HTTP / 1.1 запрос может содержать определенные кодировки контента (например, кодирование по частям), где длина может быть проанализирована в теле сообщения.

Для ответов http конец сообщения можно указать, закрыв соединение, и все, начиная с конца заголовков и заканчивая концом потока, будет рассматриваться как «сообщение». Дополнительная информация здесь

0 голосов
/ 03 августа 2011
0 голосов
/ 03 августа 2011

Другой способ узнать, где закончилось сообщение - закрыть сокет после отправки).Но лучше использовать такую ​​вещь, как content-length.

Когда я пишу свой собственный http-сервер: я пишу процедуру, которая закрывает все http-пакеты без содержимого-длины.

...