Reputation: 2598
How do I check how many available characters there in the buffer in a socket file descriptor?
I want to postpone reading bytes from a socket until at least 8 bytes are available (for the length of the following message). I am using select()
to wait for incoming data. When the read handler for a socket is called, I want it to just return without reading if less than 8 bytes are available.
Will the socket ever even be readable but only for less than 8 bytes?
Is there a Linux system call which can retrieve how many bytes are available to be read from a socket without actually reading them?
Upvotes: 2
Views: 1270
Reputation: 598299
You can use ioctl()
with the FIONREAD
(SIOCINQ
) request.
From the tcp(7) manpage:
The following ioctl(2) calls return information in
value
. The correct syntax is:int value; error = ioctl(tcp_socket, ioctl_type, &value);
ioctl_type
is one of the following:SIOCINQ
Returns the amount of queued unread data in the receive buffer. The socket must not be in LISTEN state, otherwise an error (EINVAL) is returned. SIOCINQ is defined in <linux/sockios.h>. Alternatively, you can use the synonymous FIONREAD, defined in <sys/ioctl.h>....
From the udp(7) manpage:
These ioctls can be accessed using ioctl(2). The correct syntax is:
int value; error = ioctl(udp_socket, ioctl_type, &value);
FIONREAD (SIOCINQ)
Gets a pointer to an integer as argument. Returns the size of the next pending datagram in the integer in bytes, or 0 when no datagram is pending. Warning: Using FIONREAD, it is impossible to distinguish the case where no datagram is pending from the case where the next pending datagram contains zero bytes of data. It is safer to use select(2), poll(2), or epoll(7) to distinguish these cases....
The socket will be in the readable state as long as its receive buffer contains at least 1 byte in TCP, or 1 datagram in UDP. Or, in the case of TCP, if the connection has been closed gracefully by the peer (a FIN
packet was received), in which case a subsequent read will report 0 bytes.
Upvotes: 4