Реальный ответ здесь - использовать 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 вызывает fn get_data и fn clear_socket по мере необходимости для этого конкретного приложения. Теперь вы создаете библиотеку, которую сможете носить с собой из проекта в проект и, возможно, с работы на работу, если вам так повезло, что у вас есть работодатель, который позволяет вам брать код с собой.
person
Tim
schedule
14.08.2013