Реальный ответ здесь - использовать select (2), как сказал cnicutar.Тоби, ты не понимаешь, что у тебя есть состояние гонки.Сначала вы смотрите на сокет и спрашиваете, сколько там байтов.Затем, пока ваш код обрабатывает блок «здесь нет данных», аппаратные средства и операционная система получают асинхронные байты для вашего приложения.Итак, к тому времени, когда вызывается функция recv (), ответ «нет доступных байтов» больше не верен ...
if ( ioctl (m_Socket,FIONREAD,&bytesAv) < 0 )
{ // Error
}
// BYTES MIGHT BE RECEIVED BY HARDWARE/OS HERE!
if ( bytesAv < 1 ) // AND HERE!
{
// No Data Available
// BUT BYTES MIGHT BE RECEIVED BY HARDWARE/OS HERE!
}
// AND MORE BYTES MIGHT BE RECEIVED BY HARDWARE/OS HERE!
bytesRead = recv(m_Socket,recBuffer,BUFFERLENGTH,flags);
// AND NOW bytesRead IS NOT EQUAL TO 0!
Конечно, небольшой сон, вероятно, исправил вашу программу два годаназад, но это также научило вас ужасной практике кодирования, и вы упустили возможность научиться правильно использовать сокеты с помощью select ().
Далее, как сказал Кароли Хорват, вы можете сказать recv не читатьбольше байтов, чем вы можете сохранить в буфере, который передал пользователь. Тогда интерфейс вашей функции станет «Этот fn вернет столько байтов, сколько доступно в сокете, но не больше, чем [размер буфера, который вы передали]».
Это означает, что этой функции больше не нужно беспокоиться об очистке буфера.Вызывающая сторона может вызывать вашу функцию столько раз, сколько необходимо для очистки всех ее байтов (или вы можете предоставить отдельный fn, который отбрасывает данные оптом и не связывает эту функцию в какой-либо конкретной функции сбора данных).Ваша функция более гибкая, не делая слишком много вещей.Затем вы можете создать функцию-обертку, которая отвечает вашим потребностям в передаче данных конкретного приложения и которая вызывает fn get_data fn и clear_socket fn, необходимые для этого конкретного приложения.Теперь вы создаете библиотеку, которую можете переносить из проекта в проект, и, возможно, работать на работу, если вам так повезло, что у вас есть работодатель, который позволяет вам брать с собой код.