Так работает TCP. Вы не собираетесь получать все свои данные сразу. Слишком много проблем синхронизации между отправителем и получателем, включая операционную систему отправителя, сетевую карту, маршрутизаторы, коммутаторы, сами провода, сетевую карту получателя, операционную систему и т. Д. В аппаратном обеспечении и операционной системе имеются буферы.
Вы не можете предполагать, что сеть TCP такая же, как канал ОС. Что касается конвейера, то все это программное обеспечение, поэтому для большинства сообщений не нужно платить сразу за все сообщение. С сетью вы должны предполагать, что будут проблемы с синхронизацией, даже в простой сети.
Вот почему recv () не может дать вам все данные одновременно, они могут просто не быть доступными, даже если все работает правильно. Обычно вы вызываете recv () и ловите вывод. Это должно сказать вам, сколько байтов вы получили. Если это меньше, чем вы ожидаете, вам нужно продолжать вызывать recv () (как было предложено), пока вы не получите правильное количество байтов. Имейте в виду, что в большинстве случаев recv () возвращает -1 в случае ошибки, поэтому проверьте это и проверьте в своей документации значения ERRNO. EAGAIN в частности, кажется, вызывает проблемы у людей. Вы можете прочитать об этом в Интернете для получения подробной информации, но, если я вспомню, это означает, что на данный момент нет доступных данных, и вам следует попробовать еще раз.
Кроме того, из вашего поста звучит так, что вы уверены, что отправитель отправляет данные, которые вам нужны, но для полной проверки отметьте это:
http://beej.us/guide/bgnet/output/html/multipage/advanced.html#sendall
Вы должны делать что-то похожее на конце recv () для обработки частичного получения. Если у вас фиксированный размер пакета, вы должны читать, пока не получите ожидаемый объем данных. Если у вас переменный размер пакета, вы должны читать до тех пор, пока у вас не появится заголовок, который сообщает вам, сколько данных вы отправляете (), а затем прочитать намного больше данных.