Все, что мне нужно сделать, это просто прочитать все доступные байты из сокета. Но есть одно условие: есть метод, который читает n байт из неблокирующего сокета, который я должен использовать для реализации другого метода, который будет читать все доступные байты.
Неблокирующее чтение некоторых данных определенного размера:
ssize_t read(void* buf, size_t len)
{
ssize_t bytesRead = 0;
ssize_t bytesTotallyRead = 0;
size_t bytesLeftToRead = len;
while (bytesTotallyRead < len)
{
bytesRead = ::recv(handle, (char*)buf+bytesTotallyRead, bytesLeftToRead, 0);
if (bytesRead > 0)
{
bytesTotallyRead += bytesRead;
bytesLeftToRead -= bytesRead;
}
else if (bytesRead == 0)
{
break;
}
else if (bytesRead < 0)
{
if (errno == EINTR)
{
continue;
}
else if (errno == EWOULDBLOCK)
{
int selectStatus(waitForIncomingData(500));
if (selectStatus > 0)
{
continue;
}
else
{
break;
}
}
else
{
break;
}
}
}
return (bytesRead==-1)?-1:bytesTotallyRead;
}
Поэтому я должен использовать этот метод для реализации чего-то вроде ssize_t readAllAvailable(std::vector<uint8_t> &data)
, который использует метод выше для его реализации.
Проблема здесь, как вы видите, в том, что read()
использует select()
для ожидания входящих данных, поэтому использование буфера фиксированного размера (в цикле) может привести к ожиданию 500 мс (в этом конкретном случае) после 1-й итерации, и это определенно не так. это должно быть сделано.
Это вообще возможно? Я имею в виду некоторые эффективные способы.
EWOULDBLOCK
, это не неблокирующий и не асинхронный режим. - person Daniel Kamil Kozar   schedule 29.03.2017