SIOCOUTQ SIOCINQ
SIOCINQ
Returns the amount of queued unread data in the receive
buffer. Argument is a pointer to an integer. The socket
must not be in LISTEN state, otherwise an error (EINVAL)
is returned.
SIOCATMARK
Returns true when the all urgent data has been already
received by the user program. This is used together with
SO_OOBINLINE .
Argument is an pointer to an integer for the test result.
SIOCOUTQ
Returns the amount of unsent data in the socket send queue
in the passed integer value pointer. The socket must not
be in LISTEN state, otherwise an error (EINVAL)
is returned.
Linux provides a SIOCOUTQ ioctl() to query how much data is in the TCP output buffer:
http://www.kernel.org/doc/man-pages/online/pages/man7/tcp.7.html
You can use that, plus the value of SO_SNDBUF, to determine whether the outgoing buffer has enough space for any particular message. So strictly speaking, the answer to your question is "yes".
But there are two problems with this approach. First, it is Linux-specific. Second, what are you planning to do when there is not enough space to send your whole message? Loop and call select again? But that will just tell you the socket is ready for writing again, causing you to busy-loop.
For efficiency's sake, you should probably bite the bullet and just deal with partial writes; let the network stack worry about breaking your stream up into packets for optimal throughput.
SO_SNDBUF FIONREAD MSG_PEEK
man 7 socket
You can change the size of the receive and the send buffer as follows (send buffer shown):
int buffersize = 64*1024; // 64k
setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &buffersize, sizeof(buffersize));
and to get the current size, use:
getsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char &) &buffersize, sizeof(buffersize));
ret1 = recv(fd, buffer, 32, MSG_PEEK | MSG_DONTWAIT);
MSG_PEEK
This flag causes the receive operation to return data from the beginning of the receive queue without removing that data
from the queue. Thus, a subsequent receive call will return the same data.