Home > Mobile >  Using C POSIX sockets, can you determine how many bytes a socket contains without extracting?
Using C POSIX sockets, can you determine how many bytes a socket contains without extracting?

Time:05-08

I'm working with POSIX sockets in C.

Given X, I have a need to verify that the socketfd contains at least X bytes before proceeding to perform an operation with it.

With that being said, I don't want to receive X bytes and store it into a buffer using recv as X has the potential of being very large.

My first idea was to use MSG_PEEK...

int x = 9999999
char buffer[1];
int num_bytes = recv(socketfd, buffer, X, MSG_PEEK);
(value == X) ? good : bad;
...
...
...
// Do some operation

But I'm concerned X > 1 is corrupting memory, flag MSG_TRUNC seems to resolve the memory concern but removes X bytes from socketfd.

CodePudding user response:

There's a big difference between e.g. TCP and UDP in this regards.

UDP is packet based, you send and receive packets of fixed size, basically.

TCP is a streaming protocol, where data begins to stream on connection and stops at disconnection. There are no message boundaries or delimiters in TCP, other than what you add at the application layer. It's simply a stream of bytes without any meaning (in TCP's point of view).

That means there's no way to tell how much will be received with a single recv call.

You need to come up with an application-level protocol (on top of TCP) which can either tell the size of the data to be received; For example there might be a fixed-size data-header that contains the size of the following data; Or you could have a specific delimiter between messages, something that can't occur in the stream of bytes.

Then you receive in a loop until you either have received all the data, or until you have received the delimiter. But note, with a delimiter there's the possibility that you also receive the beginning of the next message, so you need to be able to handle partial beginnings of message after the current message have been fully received.

CodePudding user response:

int num_bytes = recv(socketfd, buffer, X, MSG_PEEK);

This will copy up to X byte into buffer and return it without removing it from the socket. But your buffer is only 1 byte large. Increase your buffer.

Have you tried this?

ssize_t available = recv(socketfd, NULL, 0, MSG_PEEK | MSG_TRUNC);

Or this?

size_t available;
ioctl(socketfd, FIONREAD, &available);
  • Related