Завершение цикла " recv ()", когда вся информация считывается с помощью Winsock
У меня возникла проблема в цикле recv() для winsock. Я пытаюсь завершить цикл, когда iResult= = 0, однако цикл заканчивается только тогда, когда сокет закрывается. Похоже, что он висит на самом последнем recv (), где iResult будет равен 0. Итак, есть идеи о том, как эффективно завершить цикл? Моя конечная цель (независимо от того, является ли iResult = = 0 или нет; возможно, я иду по этому неверному пути) - остановить цикл, когда вся отправленная информация была прочитана. Вот такая петля.
do
{
iResult = recv(socket, recvbuf, BUFLEN-1, 0);
if(iResult > 0){
// Null byte :)
// Remove that garbage >:(
recvbuf[iResult] = '';
printf("Recvbuf: %snnniResult: %dn",recvbuf,iResult);
continue; // working properly
}
else if(iResult == 0)
// Connection closed properly
break;
else
{
printf("ERROR! %ld",WSAGetLastError());
break;
}
} while(iResult > 0);
Как Я сказал, что я получаю все данные, я просто не могу выйти из цикла. Следующим шагом будет запись данных обратно на сервер,но он зависает здесь до времени ожидания ping. Сокет sock_stream и BUFLEN определяется как 0x200
Спасибо
2 ответа:
По умолчанию вместо возврата 0,
recv
блоки, если нет данных для получения :Если никакие входящие данные не доступны на сокет, блоки вызова recv и ожидает поступления данных в соответствии с правила блокировки, определенные для WSARecv с флагом MSG_PARTIAL не установлен если только сокет не блокируется. В в этом случае значение SOCKET_ERROR равно возвращается с кодом ошибки, установленным в WSAEWOULDBLOCK. Отбор, WSAAsyncSelect, или WSAEventSelect функции можно использовать для определения при поступлении дополнительных данных.
Вы можете использовать ioctlsocket для перевода сокета в неблокирующий режим:
u_long iMode = 1; ioctlsocket(socket, FIONBIO, &iMode);
EDIT : Вот предложение setsockopt, которое я сделал в предыдущем rev, а затем удалил (см. комментарии):
Вы можете использовать setsockopt функция с параметром
SO_RCVTIMEO
чтобы установить сокет в таймаут наrecv
если данные отсутствуют.