Выполнение этого на уровне приложения (например, использование \0\0
в том виде, в котором вы это делаете) - правильный способ сделать это, если ваш протокол немного сложнее, чем модель с одним запросом / ответом.
HTTP 1.0, например, закрывает соединение сразу после одного запроса / ответа: клиент отправляет свою команду запроса, сервер отвечает своим ответом и закрывает соединение.
В протоколах, где имеется более сложный обменСуществуют специальные команды для указания конца сообщения.SMTP и POP3, например, разделены строкой.При отправке содержимого сообщения электронной почты через SMTP вы указываете конец сообщения, используя .
в одной строке (.
в текущем сообщении экранируется как ..
).Вы также получаете команды, такие как QUIT
, чтобы указать, что все готово.
В HTTP 1.1 набор заголовков запроса заканчивается пустой строкой (например, GET / HTTP/1.1
+ каждый заголовок в строке +пустая строка), поэтому сервер знает, где находится конец запроса.Ответы в HTTP 1.1 затем используют либо заголовок Content-Length
(чтобы сигнализировать, когда будет конец тела ответа), либо использовать кодировку chunked Transfer , которая по существу вставляет несколько разделителей, чтобы указать, естьпоступает больше данных (обычно это используется, когда размер данных заранее неизвестен серверу).(Запросы с телом также используют те же заголовки, чтобы указывать, когда запрос заканчивается.)
В противном случае серверу сложно узнать, когда он завершил чтение, поскольку, как правило, невозможно определить, является ли сокет отключен (точнее, если он все еще подключен, даже если клиент не отправляет никаких данных).Отправляя некоторый разделитель или индикатор длины на уровне приложения, вы избегаете такого рода проблем (или можете обнаружить, когда есть проблема / тайм-аут).