theroom101
theroom101

Reputation: 609

Simple tcp server c++ check available bytes

I'm trying to make a simple tcp server according to this lesson. Everything works fine, and now I'm trying to encapsulate functions in the Socket class. I try to make a method that checks the amount of available bytes to read, and I can't find necessary the function. It could be some kind of ftell() or another method.

Upvotes: 1

Views: 1521

Answers (2)

Max Dum
Max Dum

Reputation: 190

Can you elaborate on why you would need to know that?

The preferred way to read data from a socket is to first make sure it has data you can read, via a call to select and then read into a predefined array, whose size is set to that of maximum size you and the client respect. Read will then report how many bytes it has read.

I might also add you should also select a socket before writing data to it.

Finally, you might want to look up circular buffers as they offer a way to append data to a buffer without risking to fill up your RAM. You would then read the data from the circular buffer once you have enough data.

As far as I know, it is not recommended to check how many bytes are available to be read on a socket.

Upvotes: -1

Remy Lebeau
Remy Lebeau

Reputation: 595732

You should be respecting the communication protocol you are implementing on top of TCP. It dictates how you should be reading data and how you should be determining the sizes of the data to be read. If the protocol expects an integer, read an integer. If the protocol expects a length-preceded string, read the length value and then read how many bytes it specifies. If the protocol expects a delimited string, read until you encounter the delimiter. And so on.

That being said, to answer the actual question you asked - "[how to] check the amount of available bytes to read":

  • on Windows, you can use the ioctlsocket() function, where the cmd parameter is set to FIONREAD and the argp parameter is set to a pointer to a u_long variable.

    u_long bytesAvailable;
    ioctlsocket(socket, FIONREAD, &bytesAvailable);
    
  • on *Nix, you can use the ioctl() function, where the request parameter is set to FIONREAD and the third parameter is set to a pointer to a int variable.

    int bytesAvailable;
    ioctl(socket, FIONREAD, &bytesAvailable);
    

In either case, the output variable receives the number of unread bytes currently waiting on the socket. It is guaranteed that you can read at most this many bytes from the socket using recv() without blocking the calling thread (if the socket is running in a blocking mode). The socket may receive more bytes between the time you query FIONREAD and the time you call recv(), so if you try to read more than FIONREAD indicates, recv() may or may not have to block the calling thread waiting for more bytes.

Upvotes: 2

Related Questions