Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the number of bytes available in socket by 'recv' with 'MSG_PEEK' in C++

C++ has the following function to receive bytes from socket, it can check for number of bytes available with the MSG_PEEK flag. With MSG_PEEK, the returned value of 'recv' is the number of bytes available in socket:

#include <sys/socket.h>
ssize_t recv(int socket, void *buffer, size_t length, int flags); 

I need to get the number of bytes available in the socket without creating buffer (without allocating memory for buffer). Is it possible and how?

like image 350
jondinham Avatar asked Oct 20 '12 02:10

jondinham


People also ask

What does recv () return?

If successful, recv() returns the length of the message or datagram in bytes. The value 0 indicates the connection is closed.

What is Conn RECV 1024?

recv(1024) will read at most 1024 bytes, blocking if no data is waiting to be read. If you don't read all data, an other call to socket. recv won't block. socket. recv will also end with an empty string if the connection is closed or there is an error.

What is recv buffer size?

Property Value Int32. The size of the receive buffer, in bytes. The default value is 8192 bytes.

What is the difference between read () and recv ()?

The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES).


1 Answers

You're looking for is ioctl(fd,FIONREAD,&bytes_available) , and under windows ioctlsocket(socket,FIONREAD,&bytes_available).

Be warned though, the OS doesn't necessarily guarantee how much data it will buffer for you, so if you are waiting for very much data you are going to be better off reading in data as it comes in and storing it in your own buffer until you have everything you need to process something.

To do this, what is normally done is you simply read chunks at a time, such as

char buf[4096];
ssize_t bytes_read;
do {
     bytes_read = recv(socket, buf, sizeof(buf), 0);
     if (bytes_read > 0) {
         /* do something with buf, such as append it to a larger buffer or
          * process it */
     }
} while (bytes_read > 0);

And if you don't want to sit there waiting for data, you should look into select or epoll to determine when data is ready to be read or not, and the O_NONBLOCK flag for sockets is very handy if you want to ensure you never block on a recv.

like image 75
hexist Avatar answered Sep 21 '22 22:09

hexist