#c #tcp #recv
#c #tcp #recv
Вопрос:
Я использую POSIX OS (VxWorks) и хочу понять, как обрабатывать данные TCP. Я понимаю, что в UDP все действительно зависит от вас, и TCP намного лучше управляется снизу.
Предположим, удаленный сокет, к которому я подключен, обещает отправить мне данные в формате JSON. В документации просто говорится, что после установки мы отправим вам данные в формате JSON.
Используя функцию recv
в сокете TCP и предполагая, что я предоставляю ей буфер экстремального размера, должен ли я ожидать, что я всегда буду получать идеально собранные данные JSON, даже если сообщение может быть отправлено несколькими порциями на интерфейсном уровне, или мне нужно по существу проанализировать каждый полученный буфер данных, пока я не решу, что у меня есть полностью сформированное сообщение JSON?
Комментарии:
1. Вам нужно объединить все данные, а затем проанализировать их как JSON, как только вы все получите.
2. Правильно. Вы могли бы получить намного больше или намного меньше байтов, чем ожидаете. Проще всего часто использовать «Протокол фрейминга» , при котором вы отправляете, скажем, 4-байтовое целое число в конце сети в качестве первых 4 байт каждого сообщения. Затем вы продолжаете пытаться прочитать все, что еще не готово, пока не получите все это.
Ответ №1:
TCP понятия не имеет о сообщениях приложения. Вам необходимо реализовать протокол, расположенный поверх TCP, чтобы определить границы сообщений, если таковой имеется в вашем протоколе.
Комментарии:
1. Итак, если бы я сказал, эй,
send
эти JSON-данные, которые даже не такие большие (1 кб), моглиrecv
потенциально вернуть это мне во многих разных фрагментах? Может ли вообще быть конец одного объекта JSON и начало другого в одном сообщении?2. @ony_pox232 да, и да. TCP — это поток байтов, в нем нет понятия сообщений, и поэтому каждое отправляемое сообщение должно быть оформлено таким образом, чтобы получатель знал, где заканчивается одно сообщение и начинается следующее. Например, путем отправки длины JSON перед отправкой самого JSON. Или отправка завершающего разделителя после JSON, который никогда не появится в самом JSON. Каждый протокол, который выполняется поверх TCP, работает таким образом.
3. @ony_pox232 Да. Поток TCP — это просто упорядоченный поток байтов и
recv
просто возвращает вам байты, которые в данный момент доступны в потоке. Таким образом, вы можете получать всего один байт (или вообще ничего) при каждом вызовеrecv
или вы можете получать несколько гигабайт, представляющих тысячи отдельных сообщений. Это всего лишь поток байтов — вам решать проанализировать и осмыслить этот поток (в любом размере фрагмента, который вы получите).4. Ответ на первый вопрос — да. Ответ на второй вопрос заключается в том, что TCP не предотвращает этого, но протокол приложения, наложенный поверх него, может. Например, может быть указано, что отправляется только один объект JSON, а другой не отправляется до тех пор, пока первый не будет подтвержден. Вы должны фактически реализовать конкретный протокол, расположенный поверх TCP, в соответствии с его спецификацией.