Это фундаментальная часть сокетов - точнее, TCP , которая ориентирована на поток. ( UDP является пакетно-ориентированным.)
Вы никогда не должны предполагать, что вы получите столько данных, сколько запрашиваете, или что нет больше доступных данных. В основном больше данных может поступить в любое время, когда соединение открыто. (Вызов read / recv / what, вероятно, вернет определенное значение, означающее «другой конец закрыл соединение.)
Это означает, что вы должны разработать свой протокол, чтобы справиться с этим - если вы фактически пытаетесь передать отдельные сообщения от А до Б, есть два распространенных способа сделать это:
- Префикс каждого сообщения длиной. Читатель сначала читает длину, затем продолжает читать данные, пока они не будут прочитаны столько, сколько нужно.
- Иметь какой-либо терминатор / разделитель сообщений. Это сложнее, так как в зависимости от того, что вы делаете, вам, возможно, нужно знать о возможности прочтения начала следующего сообщения, пока вы читаете первое. Это также означает «понимание» самих данных в «читающем» коде, а не просто произвольное чтение байтов. Тем не менее, это означает, что отправителю не нужно знать, как долго сообщение перед отправкой.
(Другая альтернатива - иметь только одно сообщение для всего соединения - т.е. вы читаете, пока соединение не будет закрыто.)