how can i get the number of bytes available to read on async socket on linux?

asyncsocket, c++, linux, sockets

Solution

From `man 7 tcp`:

int value;
error = ioctl(sock, FIONREAD, &value);

Or alternatively `SIOCINQ`, which is a synonym of `FIONREAD`.

Anyway, I'd recommend just to use `recv` in non-blocking mode in a loop until it returns `EWOULDBLOCK`.

UPDATE:

From your comments below I think that this is not the appropriate solution for your problem.

Imagine that your header is 8 bytes and you receive just 4; then your `poll/select` will return `EPOLLIN`, you will check the `FIONREAD`, see that the header is not yet complete and wait for more bytes. But these bytes never arrive, so you keep on getting `EPOLLIN` on every call to `poll/select` and you have a no-op busy-loop. That is, `poll/select` are level-triggered. Not that an edge triggered function solves your problem either.

At the end you are far better doing a bit of work, adding a buffer per connection, and queuing the bytes until you have enough. It is not as difficult as it seems and it works far better. For example, something like that:

struct ConnectionData
{
    int sck;
    std::vector<uint8_t> buffer;
    size_t offset, pending;
};

void OnPollIn(ConnectionData *d)
{
    int res = recv(d->sck, d->buffer.data() + offset, d->pending);
    if (res < 0) 
        handle_error();
    d->offset += res;
    d->pending -= res;
    
    if (d->pending == 0)
        DoSomethingUseful(d);
}

And whenever you want to get a number of bytes:

void PrepareToRecv(ConnectionData *d, size_t size)
{
    d->buffer.resize(size);
    d->offset = 0;
    d->pending = size;
}

Problem

I have a simple tcp/ip server written in c++ on linux. I'm using asynchronous sockets and epoll. Is it possible to find out how many bytes are available for reading, when i get the EPOLLIN event?

Original source