slowcheetah
slowcheetah

Reputation: 67

C++ non-blocking reading

All I need to do is just to read all available bytes from socket. But there is one condition: there is a method which reads n bytes from non-blocking socket which I have to use for implementation of another method which is going to read all available bytes.

Non-blocking reading of some data with defined size:

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;
}

So I have to use this method to implement something like ssize_t readAllAvailable(std::vector<uint8_t> &data) which uses method above for it's implementation.

The problem here, as you see, that read() uses select() for waiting for incoming data so using of buffer of fixed size (in loop) might lead to 500 ms (in this concrete case) waiting after 1st iteration and this is definitely not the way it should be done.

Is it possible at all? I mean some efficient ways.

Upvotes: 0

Views: 3074

Answers (1)

user207421
user207421

Reputation: 311039

there is a method which reads n bytes from socket asynchronously

No there isn't. There is a method which uses non-blocking mode and select() to reimplement blocking mode. There is nothing 'asynchronous' about it whatsoever. From the point of view of the caller it is blocking-mode. It is poorly, indeed incorrectly, conceived, and should be thrown away. The code you have posted is completely and utterly pointless. It's just a complicated way of implementing a blocking read loop. Use blocking mode. In effect, you already are, but with more system calls. And lose the select() call and EAGAIN/EWOUDLBLOCK stuff.

which I have to use for implementation of another method which is going to read all available bytes. ... The problem here, as you see, that read() uses select() for waiting for incoming data so using of buffer of fixed size (in loop) might lead to 500 ms (in this concrete case) waiting after 1st iteration

No it isn't. select() will return immediately data becomes available on the socket. No 500ms unless there is no data. And 'using a buffer of fixed size' has exactly nothing to do with it.

and this is definitely not the way it should be done.

It isn't the way it is done.

There is no problem here to solve.

Upvotes: 2

Related Questions