Это задуманно и следовало ожидать.
Короткий ответ на ваш вопрос: вы должны продолжать звонить «читать», пока не получите все ожидаемые данные.То есть:
int total_bytes = 0;
int expected = BUFSIZE;
int bytes_read;
char *buffer = malloc(BUFSIZE+1); // +1 for null at the end
while (total_bytes < expected)
{
int bytes_read = read(mSockFD, buffer+total_bytes, BUFSIZE-total_bytes);
if (bytes_read <= 0)
break;
total_bytes += bytes_read;
}
buffer[total_bytes] = 0; // null terminate - good for debugging as a string
Из моего опыта, одно из самых больших заблуждений (приводящих к ошибкам), что вы получите столько данных, сколько запрашиваете.Я видел код доставки в реальных продуктах, написанный с ожиданием того, что сокеты работают таким образом (и никто не уверен, почему он не работает надежно).
Когда другая сторона отправляет N байтов, вы можетеповезет и получит все сразу.Но вы должны запланировать получение N байтов, распределенных между несколькими вызовами recv.За исключением реальной сетевой ошибки, вы в конечном итоге получите все N байтов.Сегментация, фрагментация, размер окна TCP, MTU и схема разбиения данных на уровне сокетов являются причинами всего этого.При получении частичных данных уровень TCP не знает, сколько еще предстоит сделать.Он просто передает то, что имеет, в приложение.Приложение решает, достаточно ли оно получено.
Аналогично, вызовы "send" могут объединяться в один пакет вместе.
Могут быть ioctl и такие, которые сделают сокетблокировать, пока все ожидаемые данные не будут получены.Но я не знаю ничего лишнего.
Кроме того, не используйте чтение и запись для сокетов.Используйте recv и отправьте.
Прочитайте эту книгу .Это изменит вашу жизнь в отношении сокетов и TCP: